You are here

views_rdf.module in Views Datasource 5

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

Provides Views plugin for rendering node content as RDF.

File

views_rdf.module
View source
<?php

/**
 * @file
 * Provides Views plugin for rendering node content as RDF.
 */

/**
 * Implementation of hook_views_style_plugins
 * @return array with style plugin declarations. 
 */
function views_rdf_views_style_plugins() {
  return array(
    'views_rdf_foaf' => array(
      'name' => t('Views RDF: FOAF RDF data document'),
      'theme' => 'views_rdf_foaf',
      'needs_table_header' => TRUE,
      'needs_fields' => TRUE,
      'even_empty' => TRUE,
    ),
    'views_rdf_sioc' => array(
      'name' => t('Views RDF: SIOC RDF data document'),
      'theme' => 'views_rdf_sioc',
      'needs_table_header' => TRUE,
      'needs_fields' => TRUE,
      'even_empty' => TRUE,
    ),
  );
}

/*
 * Implementation of hook_views_arguments to add the RDF argument selectors.
 * @returns array of arguments
 */
function views_rdf_views_arguments() {
  $arguments = array(
    'rdf_foaf' => array(
      'name' => t('Views RDF: FOAF data document selector'),
      'handler' => 'views_rdf_foaf_handler',
      'option' => 'string',
      'help' => t('This argument specifies a document selector; it will only provide a method for rendering the current view as a FOAF RDF document.'),
    ),
    'rdf_foaf_format' => array(
      'name' => t('FOAF RDF output format'),
      'handler' => 'views_rdf_foaf_handler',
      'option' => array(
        '#type' => 'select',
        '#options' => array(
          'XML' => t('RDF/XML output'),
          'N3' => t('RDF/N3 output'),
        ),
      ),
      'help' => t('This argument specifies the output format of the RDF document - RDF/XML or RDF/N3.'),
    ),
    'rdf_sioc' => array(
      'name' => t('Views RDF: SIOC data document selector'),
      'handler' => 'views_rdf_sioc_handler',
      'option' => 'string',
      'help' => t('This argument specifies a document selector; it will only provide a method for rendering the current view as a SIOC RDF document.'),
    ),
  );
  return $arguments;
}

/**
 * handler for our own RDF FOAF argument handler
 */
function views_rdf_foaf_handler($op, &$query, $argtype, $arg = '') {
  if ($op == 'filter') {
    views_rdf_foaf_views_argument('argument', $GLOBALS['current_view'], $arg);
  }
}

/**
 * argument hook that will display the RDF data document or display export icons.
 */
function views_rdf_foaf_views_argument($op, &$view, $arg) {
  if ($op == 'argument' && $arg == 'rdf_foaf') {
    $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 == 'rdf_foaf') {
        if ($image = theme('image', drupal_get_path('module', 'views_rdf') . '/foaf80x15.png', t('FOAF'), t('Show @title as a FOAF document.', array(
          '@title' => $title,
        )))) {
          $links[] = l($image, $url, array(
            'class' => 'rdf-icon',
          ), $url_filter, NULL, FALSE, TRUE);
          return implode('&nbsp;&nbsp;', $links);
        }
      }
    }
  }
}

/**
 * handler for our own RDF SIOC argument handler
 */
function views_rdf_sioc_handler($op, &$query, $argtype, $arg = '') {
  if ($op == 'filter') {
    views_rdf_sioc_views_argument('argument', $GLOBALS['current_view'], $arg);
  }
}

/**
 * argument hook that will display the RDF data document or display export icons.
 */
function views_rdf_sioc_views_argument($op, &$view, $arg) {
  if ($op == 'argument' && $arg == 'rdf_sioc') {
    $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 == 'rdf_sioc') {
        if ($image = theme('image', drupal_get_path('module', 'views_rdf') . '/sioc100x98.png', t('SIOC'), t('Show @title as a SIOC document.', array(
          '@title' => $title,
        )))) {
          $links[] = l($image, $url, array(
            'class' => 'rdf-icon',
          ), $url_filter, NULL, FALSE, TRUE);
          return implode('&nbsp;&nbsp;', $links);
        }
      }
    }
  }
}

/*
 * describes how to theme an RDF FOAF view
 */
function theme_views_rdf_foaf($view, $nodes, $type) {
  views_rdf_foaf_xml_render($view->vid, $nodes, $type);
}

/*
 * describes how to theme an RDF SIOC view
 */
function theme_views_rdf_sioc($view, $nodes, $type) {
  views_rdf_sioc_xml_render($view->vid, $nodes, $type);
}

/**
 * post view to display the render icons
 */
function views_rdf_views_post_view($view, $items, $output) {
  $links = '';
  foreach ($view->argument as $id => $argument) {
    if ($argument['type'] == 'rdf_foaf') {
      $links .= views_rdf_foaf_views_argument('post_view', $view, $argument['type'], '');
    }
    if ($argument['type'] == 'rdf_sioc') {
      $links .= views_rdf_sioc_views_argument('post_view', $view, $argument['type'], '');
    }
  }
  return $links;
}
function views_rdf_foaf_xml_render($vid, $nodes, $type) {
  $view = views_load_view($vid);
  $fields = _views_get_fields();
  $xml .= '<?xml version="1.0" encoding="UTF-8" ?>' . "\n";
  $xml .= '<!-- generator="Drupal Views_Datasource.Module" -->' . "\n";
  $xml .= '<rdf:RDF xmlns="http://xmlns.com/foaf/0.1"' . "\n";
  $xml .= '  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"' . "\n";
  $xml .= '  xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"' . "\n";
  $xml .= '  xmlns:dc="http://purl.org/dc/elements/1.1/"' . "\n";
  $xml .= '  xmlns:foaf="http://xmlns.com/foaf/0.1/">' . "\n";
  foreach ($nodes as $node) {
    $xml .= "<foaf:Person>\n";
    foreach ($view->field as $field) {
      if ($fields[$field['id']]['visible'] !== false) {
        $label = $field['label'] ? $field['label'] : $fields[$field['fullname']]['name'];

        /*strip illegal XML characters*/
        $label = views_rdf_strip_illegal_chars($label);
        $value = views_rdf_strip_illegal_chars(views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $node, $view));

        //echo("$label:$value");
      }
      else {
        continue;
      }
      if (is_null($value) || $value === '') {
        continue;
      }
      if (stripos($label, 'firstname') !== false) {
        $xml .= "  <foaf:firstName>{$value}</foaf:firstName>\n";
        continue;
      }
      if (stripos($label, 'surname') !== false) {
        $xml .= "  <foaf:surName>{$value}</foaf:surName>\n";
        continue;
      }
      if (stripos($label, 'name') !== false && !(stripos($label, 'surname') !== false || stripos($label, 'firstname') !== false)) {
        if (stripos($xml, "<foaf:name>") == false) {
          $xml .= "  <foaf:name>{$value}</foaf:name>\n";
        }
        continue;
      }
      if (stripos($label, 'title') !== false) {
        $xml .= "  <foaf:title>{$value}</foaf:title>\n";
        continue;
      }
      if (stripos($label, 'nick') !== false) {
        $xml .= "  <foaf:nick>{$value}</foaf:nick>\n";
        continue;
      }
      if (stripos($label, 'mbox_sha1sum') !== false) {
        $xml .= "  <foaf:mbox_sha1sum>{$value}</foaf:mbox_sha1sum>\n";
        continue;
      }
      if (stripos($label, 'mbox') !== false && !(stripos($label, 'mbox_sha1sum') !== false)) {
        $xml .= "  <foaf:mbox>{$value}</foaf:mbox>\n";
        continue;
      }
      if (stripos($label, 'openid') !== false) {
        $xml .= "  <foaf:openid>{$value}</foaf:openid>\n";
        continue;
      }
      if (strpos($label, 'workplaceHomepage') !== false) {
        $xml .= '  <foaf:workplaceHomepage rdf:resource="' . $value . '"/>' . "\n";
        continue;
      }
      if (strpos($label, 'homepage') !== false) {
        $xml .= '  <foaf:homepage rdf:resource="' . $value . '"/>' . "\n";
        continue;
      }
      if (stripos($label, 'weblog') !== false) {
        $xml .= '  <foaf:weblog rdf:resource="' . $value . '"/>' . "\n";
        continue;
      }
      if (strpos($label, 'img') !== false) {
        $xml .= '  <foaf:img rdf:resource="' . $value . '"/>' . "\n";
        $xml .= '  <foaf:depiction rdf:resource="' . $value . '"/>' . "\n";
        continue;
      }
      if (stripos($label, 'member') !== false) {
        $xml .= "  <foaf:member>{$value}</foaf:member>\n";
        continue;
      }
      if (stripos($label, 'phone') !== false) {
        $xml .= "  <foaf:phone>{$value}</foaf:phone>\n";
        continue;
      }
      if (stripos($label, 'jabberID') !== false) {
        $xml .= "  <foaf:jabberID>{$value}</foaf:jabberID>\n";
        continue;
      }
      if (stripos($label, 'msnChatID') !== false) {
        $xml .= "  <foaf:msnChatID>{$value}</foaf:msnChatID>\n";
        continue;
      }
      if (stripos($label, 'aimChatID') !== false) {
        $xml .= "  <foaf:aimChatID>{$value}</foaf:aimChatID>\n";
        continue;
      }
      if (stripos($label, 'yahooChatID') !== false) {
        $xml .= "  <foaf:yahooChatID>{$value}</foaf:yahooChatID>\n";
        continue;
      }
    }
    $xml .= "</foaf:Person>\n";
  }
  $xml .= "</rdf:RDF>\n";
  drupal_set_header('Content-Type: text/xml');

  //var_dump($view);
  print $xml;
  module_invoke_all('exit');
  exit;
}
function views_rdf_sioc_xml_render($vid, $nodes, $type) {
  $view = views_load_view($vid);
  $result = views_build_view('items', $view);
  $fields = _views_get_fields();
  $users_xml = array();
  $nodes_xml = array();
  global $base_url;
  $xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
  $xml .= '<!-- generator="Drupal Views_Datasource.Module" -->' . "\n";
  $xml .= "<rdf:RDF\r\n";
  $xml .= "  xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\r\n";
  $xml .= "  xmlns:rdfs=\"http://www.w3.org/2000/01/rdf-schema#\"\r\n";
  $xml .= "  xmlns:sioc=\"http://rdfs.org/sioc/ns#\"\r\n";
  $xml .= "  xmlns:sioct=\"http://rdfs.org/sioc/terms#\"\r\n";
  $xml .= "  xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\r\n";
  $xml .= "  xmlns:dcterms=\"http://purl.org/dc/terms/\"\r\n";
  $xml .= "  xmlns:admin=\"http://webns.net/mvcb/\"\r\n";
  $xml .= "  xmlns:foaf=\"http://xmlns.com/foaf/0.1/\">\r\n";
  $xml .= "<foaf:Document rdf:about=\"" . url($view->real_url, NULL, NULL, true) . "\">\n";
  $xml .= "  <dc:title>SIOC profile for: " . variable_get('site_name', 'drupal') . "</dc:title>\n";
  $xml .= "  <dc:description>\n";
  $xml .= "    A SIOC profile describes the structure and contents of a weblog in a machine readable form. For more information please refer to http://sioc-project.org/.\n    A Post is an article or message posted by a User to a Forum or Site. A series of Posts \n    may be threaded if they share a common subject and are connected by reply or \n    by date relationships. Posts will have content and may also have attached \n    files, which can be edited or deleted by the Moderator of the Forum or Site that \n    contains the Post.\n";
  $xml .= "  </dc:description>\n";

  //$xml .= "  <foaf:primaryTopic rdf:resource=\"$node_url\"/>\n";
  $xml .= "  <admin:generatorAgent rdf:resource=\"http://drupal.org/project/views_datasource\"/>\n";
  $xml .= "</foaf:Document>\n";
  foreach ($nodes as $node) {
    $nid = false;
    $type = false;
    $created = false;
    $changed = false;
    $last_updated = false;
    $title = false;
    $body = false;
    $uid = false;
    $users_name = false;
    if ($node->nid) {
      $nid = $node->nid;
    }
    if ($node->node_title) {
      $title = $node->node_title;
    }
    if ($node->node_created) {
      $created = $node->node_created;
    }
    if ($node->node_changed) {
      $changed = $node->node_changed;
    }
    if ($node->node_type) {
      $type = $node->node_type;
    }
    if ($node->users_name) {
      $users_name = $node->users_name;
    }
    if ($node->node_comment_statistics_last_changed) {
      $last_updated = $node->node_comment_statistics_last_changed;
    }
    foreach ($view->field as $field) {
      if ($fields[$field['id']]['visible'] !== false) {
        $label = $field['label'] ? $field['label'] : $fields[$field['fullname']]['name'];

        /*strip illegal XML characters*/
        $value = views_rdf_strip_illegal_chars(views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $node, $view));
      }
      else {
        continue;
      }
      if (stripos($label, 'nodebody') !== false || stripos($label, 'node_body') !== false || stripos($label, 'body') !== false) {
        $body = $value;
        continue;
      }
    }
    if (!$nid) {
      drupal_set_message('The node nid field must be present.', 'error');
      return;
    }
    if (!$type) {
      drupal_set_message('The node type field must be present.', 'error');
      return;
    }
    if (!$created) {
      drupal_set_message('The node created field must be present.', 'error');
      return;
    }
    if (!$changed) {
      drupal_set_message('The node changed field must be present.', 'error');
      return;
    }
    if (!$last_updated) {
      drupal_set_message('The node last-updated field must be present.', 'error');
      return;
    }
    if (!$title) {
      drupal_set_message('The node title field must be present.', 'error');
      return;
    }
    if (!$body) {
      drupal_set_message('The node body field must be present.', 'error');
      return;
    }
    if (!$users_name) {
      drupal_set_message('The node author field must be present.', 'error');
      return;
    }
    $user = user_load(array(
      'name' => $users_name,
    ));
    if (!array_key_exists($user->uid, $users_xml)) {
      $users_xml[$user->uid] = rdf_sioc_xml_user_render($user);
    }
    else {
      continue;
    }
    if ($type == 'page' || $type == 'story' || $type == 'forum' || $type == 'blog') {
      $nodes_xml[$nid] = rdf_sioc_xml_story_render($nid, $title, $type, $created, $changed, $last_updated, $user->uid, $body, &$users_xml);
    }
  }

  //drupal_set_header('Content-Type: text/xml');

  //var_dump($view);

  //var_dump(rdf_sioc_xml_user_render($user));

  //var_dump(user_load(array('name' => $users_name)));
  $xml .= implode("", $users_xml);
  $xml .= implode("", $nodes_xml);
  drupal_set_header('Content-Type: application/rdf+xml');
  print $xml;
  module_invoke_all('exit');
  exit;
}
function rdf_sioc_xml_user_render($user) {
  $xml .= "<foaf:Person rdf:about=\"" . url('/user/' . $user->uid, NULL, NULL, true) . "\">\n";
  $xml .= "  <foaf:name>{$user->name}</foaf:name>\n";
  $xml .= "  <foaf:mbox_sha1sum>" . md5('mailto:' . $user->email) . "</foaf:mbox_sha1sum>\n";
  $xml .= "  <foaf:holdsAccount>\n";
  $xml .= "    <sioc:User rdf:nodeID=\"{$user->uid}\">\n";
  $xml .= "      <sioc:name>{$user->name}</sioc:name>\n";
  $xml .= "      <sioc:email rdf:resource=\"mailto:{$user->email}\"/>\n";
  $xml .= "      <sioc:email_sha1>" . md5('mailto:' . $user->email) . "</sioc:email_sha1>\n";
  $xml .= "      <sioc:link rdf:resource=\"" . url('/user/' . $user->uid, NULL, NULL, true) . "\" rdfs:label=\"{$user->name}\"/>\n";
  $roles = array();
  $roles_query = db_query("SELECT r.name AS name, r.rid AS rid FROM {users_roles} ur, {role} r WHERE ur.uid = %d AND ur.rid = r.rid", $user->uid);
  while ($role = db_fetch_object($roles_query)) {
    $roles[$role->rid] = $role->name;
  }
  if (count($roles) > 0) {
    $xml .= "      <sioc:has_function>\n";
    foreach ($roles as $rid => $name) {
      $xml .= "        <sioc:Role><rdfs:label><![CDATA[{$name}]]></rdfs:label></sioc:Role>\n";
    }
    $xml .= "      </sioc:has_function>\n";
  }
  $xml .= "    </sioc:User>\n";
  $xml .= "  </foaf:holdsAccount>\n";
  $xml .= "</foaf:Person>\n";
  return $xml;
}
function rdf_sioc_xml_story_render($nid, $title, $type, $created, $changed, $last_updated, $uid, $body, &$users_xml) {
  $node_url = url('/node/' . $nid, NULL, NULL, true);
  $xml .= "<sioc:Post rdf:about=\"{$node_url}\">\n";
  $xml .= "  <dc:title>{$title}</dc:title>\n";
  $xml .= "  <sioc:content>\n ";
  $xml .= "    <![CDATA[{$body}]]>\n";
  $xml .= "  </sioc:content>\n";
  $xml .= "  <dc:created>" . date(DATE_ISO8601, $created) . "</dc:created>\n";
  $xml .= "  <dc:modified>" . date(DATE_ISO8601, $changed) . "</dc:modified>\n";
  $xml .= "  <sioc:link rdf:resource=\"{$node_url}\" rdfs:label=\"{$title}\" />\n";
  $xml .= "  <sioc:has_creator rdf:nodeID=\"{$uid}\"/>\n";

  /*Add taxonomy terms as SIOC topics*/
  $query = db_query('SELECT tn.tid AS tid, td.name AS name FROM {term_node} tn, {term_data} td WHERE td.tid = tn.tid AND tn.nid = %d', $nid);
  while ($term = db_fetch_object($query)) {
    $taxonomy_terms = "  <sioc:topic rdfs:label=\"{$term->name}\" rdf:resource=\"" . url("taxonomy/term/{$term->tid}", NULL, NULL, true) . "\" />\n";
  }
  $xml .= $taxonomy_terms;

  /*Add comments as SIOC replies*/
  $query_count = 'SELECT COUNT(*) FROM {comments} WHERE nid = %d AND status = %d';
  $query = 'SELECT c.cid as cid, c.pid, c.nid, c.subject, c.comment, c.format, c.timestamp, c.name, c.mail, c.homepage, u.uid, u.name AS registered_name, u.signature, u.picture, u.data, c.thread, c.status FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.nid = %d and c.status = %d ORDER BY SUBSTRING(c.thread, 1, (LENGTH(c.thread) - 1))';
  $query_args = array(
    $nid,
    COMMENT_PUBLISHED,
  );
  $query = db_rewrite_sql($query, 'c', 'cid');
  $comment_children = 0;
  $num_rows = FALSE;
  $comments = '';
  $result = db_query($query, $query_args);
  while ($comment = db_fetch_object($result)) {
    $comment = drupal_unpack($comment);
    $comments .= "  <sioc:has_reply>\n";
    $comments .= "    <sioc:Post rdf:about=\"{$node_url}#comment-{$comment->cid}\">\n";
    if ($comment->subject) {
      $comments .= "      <dc:title>{$comment->subject}</dc:title>\n";
    }
    if ($comment->timestamp) {
      $comments .= "      <dc:created>" . date(DATE_ISO8601, $comment->timestamp) . "</dc:created>\n";
    }
    if ($comment->uid) {
      if (!array_key_exists($comment->uid, $users_xml)) {
        $users_xml[$comment->uid] = rdf_sioc_xml_user_render(user_load(array(
          'uid' => $comment->uid,
        )));
      }
      $comments .= "    <sioc:has_creator>\n";
      $comments .= "      <sioc:User>\n";
      $comments .= "        <sioc:name>{$comment->registered_name}</sioc:name>\n";
      $comments .= "        <sioc:email rdf:resource=\"mailto:{$comment->mail}\"/>\n";
      $comments .= "         <sioc:link rdf:resource=\"" . url('/user/' . $comment->uid, NULL, NULL, true) . "\" rdfs:label=\"{$comment->registered_name}\"/>\n";
      $comments .= "      </sioc:User>\n";
      $comments .= "    </sioc:has_creator>\n";
    }
    $comments .= "      <sioc:content><![CDATA[{$comment->comment}]]></sioc:content>\n";
    $comments .= "    </sioc:Post>\n";
    $comments .= "  </sioc:has_reply>\n";
  }
  $xml .= $comments;
  $xml .= "</sioc:Post>\n";
  return $xml;
}

/**
 * Strips illegal Unicode characters and encodes entities in string
 *
 * @param string $input
 * @return string
 */
function views_rdf_strip_illegal_chars($input) {
  $output = preg_replace('/[\\x{80}-\\x{A0}' . '\\x{01}-\\x{1F}' . '\\x{AD}' . '\\x{2000}-\\x{200F}' . '\\x{2028}-\\x{202F}' . '\\x{205F}-\\x{206F}' . '\\x{FEFF}' . '\\x{FF01}-\\x{FF60}' . '\\x{FFF9}-\\x{FFFD}' . '\\x{0}]/u', '', $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('>', '&rt;', $output); //encode right-angled bracket
  return check_plain(strip_tags($output));
}

Functions

Namesort descending Description
rdf_sioc_xml_story_render
rdf_sioc_xml_user_render
theme_views_rdf_foaf
theme_views_rdf_sioc
views_rdf_foaf_handler handler for our own RDF FOAF argument handler
views_rdf_foaf_views_argument argument hook that will display the RDF data document or display export icons.
views_rdf_foaf_xml_render
views_rdf_sioc_handler handler for our own RDF SIOC argument handler
views_rdf_sioc_views_argument argument hook that will display the RDF data document or display export icons.
views_rdf_sioc_xml_render
views_rdf_strip_illegal_chars Strips illegal Unicode characters and encodes entities in string
views_rdf_views_arguments
views_rdf_views_post_view post view to display the render icons
views_rdf_views_style_plugins Implementation of hook_views_style_plugins