<?php
// $Id: atom.module,v 1.16.2.4 2006/01/13 04:03:18 deekayen Exp $

/**
 * Implementation of hook_help
 *
 * @return string
 */
function atom_help($section) {
  $output = '';

  switch ($section) {
    case 'admin/modules#description':
      $output = t('Provides an Atom 1.0 feed');
      break;
    case 'admin/settings/atom':
      if (user_access('administer atom')) {
        $output = t('Ad unit insertion currently only works with Yahoo! Publisher Network. '
                   .'When inserting Yahoo! RSS ad unit code, select Wordpress format, '
                   .'replace instances of &lt;?php the_ID() ?&gt; with %id, and '
                   .'&lt;?php echo urlencode(get_permalink()) ?&gt; with %link to '
                   .'properly insert substitutes. For example, a correct '
                   .'Yahoo! RSS ad unit would look similar to the following, '
                   .'only with your unique rss number and pid:<br /><blockquote>'
                   .'&lt;a href="http://ypn-rss.overture.com/rss/11111/%id/click/"&gt;'
                   .'&lt;img src="http://ypn-rss.overture.com/rss/11111/%id/img/?url=%link&amp;pid=12345678" border="0" /&gt;&lt;/a&gt;</blockquote>');
      }
      break;
  }
  return $output;
}

/**
 * Valid permissions for the atom module
 *
 * @return array An array of valid permissions for the atom module
 */
function atom_perm() {
  return array('administer atom');
}

/**
 * Implementation of hook_menu
 *
 * @return array
 */
function atom_menu($may_cache) {
  $items = array();
  if(arg(0) == 'blog' && is_numeric(arg(1))) {
    drupal_set_html_head('<link rel="alternate" type="application/atom+xml" title="Atom" href="'. url('blog/'. arg(1) .'/atom/feed', NULL, NULL, TRUE) .'" />');
  }
  elseif(arg(0) == 'blog') {
    drupal_set_html_head('<link rel="alternate" type="application/atom+xml" title="Atom" href="'. url('blog/atom/feed', NULL, NULL, TRUE) .'" />');
  }
  else {
    drupal_set_html_head('<link rel="alternate" type="application/atom+xml" title="Atom" href="'. url('atom/feed', NULL, NULL, TRUE) .'" />');
  }
  if ($may_cache) {
    $items[] = array('path' => 'atom/feed', 'title' => t('atom feed'),
                     'callback' => 'atom_feed',
                     'access' => user_access('access content'),
                     'type' => MENU_CALLBACK);
    $items[] = array('path' => 'blog/atom/feed', 'title' => t('atom blog feed'),
                     'callback' => 'atom_blog_feed',
                     'access' => user_access('access content'),
                     'type' => MENU_CALLBACK);
  }
  if (is_numeric(arg(1))) {
    $items[] = array('path' => 'blog/'. arg(1) .'/atom/feed', 'title' => t('atom blog feed'),
                     'callback' => 'atom_user_blog_feed',
                     'access' => user_access('access content'),
                     'type' => MENU_CALLBACK);
  }
  return $items;
}

/**
 * Produces an atom 1.0 feed for the front page content.
 */
function atom_feed() {
  if(strpos(arg(2), 'atom') === 0 || strpos(arg(2), 'feed') === 0) {
    die(drupal_not_found());
  }
  global $base_url;
  $nodes = db_query_range("SELECT n.nid FROM {node} n WHERE n.promote = '1' AND n.status = '1' ORDER BY n.created DESC", 0, variable_get('atom_feed_entries', 15));

  $feed_info = array();
  $feed_info['title']    = strip_tags(variable_get('site_name', 'Drupal'));
  $feed_info['subtitle'] = strip_tags(variable_get('site_slogan', ''));
  $feed_info['html_url'] = $base_url;
  $feed_info['atom_url'] = url('atom/feed', NULL, NULL, true);
  _atom_print_feed($nodes, $feed_info);
}

function atom_blog_feed() {
  if(strpos(arg(3), 'atom') === 0 || strpos(arg(3), 'feed') === 0) {
    die(drupal_not_found());
  }
  $nodes = db_query_range("SELECT n.nid FROM {node} n WHERE n.type = 'blog' AND n.status = '1' ORDER BY n.created DESC", 0, variable_get('atom_feed_entries', 15));

  $feed_info = array();
  $feed_info['title']    = strip_tags(sprintf(t('%s blogs'), variable_get('site_name', 'Drupal')));
  $feed_info['subtitle'] = strip_tags(variable_get('site_slogan', ''));
  $feed_info['html_url'] = url('blog', NULL, NULL, true);
  $feed_info['atom_url'] = url('blog/atom/feed', NULL, NULL, true);
  _atom_print_feed($nodes, $feed_info);
}

function atom_user_blog_feed() {
  if(strpos(arg(4), 'atom') === 0 || strpos(arg(4), 'feed') === 0) {
    die(drupal_not_found());
  }
  $user_result = db_query_range("SELECT u.name FROM {users} u WHERE u.uid = %d", arg(1), 0, 1);
  if(!$user = db_result($user_result)) {
    return t('User does not exist.');
  }

  $nodes = db_query_range("SELECT n.nid FROM {node} n WHERE n.type = 'blog' AND n.uid = %d AND n.status = '1' ORDER BY n.created DESC", arg(1), 0, variable_get('atom_feed_entries', 15));

  $feed_info = array();
  $feed_info['title']    = sprintf(t("%s's blog"), $user);
  $feed_info['html_url'] = url('blog/'. arg(1), NULL, NULL, true);
  $feed_info['atom_url'] = url('blog/'. arg(1) .'/atom/feed', NULL, NULL, true);
  _atom_print_feed($nodes, $feed_info);
}

/**
 * prints feed information from query of either front page or blog content
 *
 * @param object $nodes query result
 * @param array feed information
 */
function _atom_print_feed($nodes, $feed_info) {
  $output = '';
  $last_mod = 0;
  while ($node = db_fetch_object($nodes)) {
    $item = node_load(array('nid' => $node->nid));
    $link = url("node/$node->nid", NULL, NULL, true);

    if (node_hook($item, 'view')) {
      node_invoke($item, 'view', TRUE, FALSE);
    }
    else {
      $item = node_prepare($item, TRUE);
    }

    // Allow modules to change $node->teaser before viewing.
    node_invoke_nodeapi($item, 'view', true, false);

    $output .= "  <entry>\n";
    $output .= '    <title>'. check_plain(strip_tags($item->title)) ."</title>\n";
    $output .= '    <link rel="alternate" type="text/html" href="'. $link .'" />'. "\n";
    $output .= '    <id>'. $link ."</id>\n";
    $output .= '    <published>'. _atom_timestamp2w3dtf($item->created) ."</published>\n";
    $output .= '    <updated>'. _atom_timestamp2w3dtf($item->changed) ."</updated>\n";
    $last_mod = $item->changed;
    $output .= "    <author>\n";
    if ($item->name) {
      $output .= '      <name>'. $item->name ."</name>\n";
    }
    else {
      $output .= '      <name>'. variable_get('anonymous', 'Anonymous') ."</name>\n";
    }
    $output .= "    </author>\n";
    if (module_exist('taxonomy')) {
      $terms = taxonomy_node_get_terms($item->nid);
      foreach ($terms as $term) {
        $output .= '    <category term="'. check_plain(strip_tags($term->name)) . '" />'. "\n";
      }
    }
    // Summary
    $output .= '    <summary type="html"><![CDATA[';
    $output .= check_markup($item->teaser);
    $output .= "    ]]></summary>\n";

    // Body
    $output .= '    <content type="html"><![CDATA[';
    $output .= variable_get('atom_ad_location', 'off') == 'prepend' ? str_replace('%link', urlencode($link), str_replace('%id', $node->nid, variable_get('atom_ad_code', ''))) : '';
    $output .= check_markup($item->body);
    $output .= variable_get('atom_ad_location', 'off') == 'append' ? str_replace('%link', urlencode($link), str_replace('%id', $node->nid, variable_get('atom_ad_code', ''))) : '';
    $output .= "    ]]></content>\n";
    $output .= "  </entry>\n";
  }

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

  print '<?xml version="1.0" encoding="utf-8"?>'. "\n";
  print '<feed xmlns="http://www.w3.org/2005/Atom">'. "\n";
  print '  <title>'. $feed_info['title'] ."</title>\n";
  print $feed_info['subtitle'] == '' ? '' : '  <subtitle>'. $feed_info['subtitle'] . "</subtitle>\n";
  print '  <link rel="alternate" type="text/html" href="'.$feed_info['html_url'] .'"/>'. "\n";
  print '  <link rel="self" type="application/atom+xml" href="'. $feed_info['atom_url'] .'"/>'. "\n";
  print '  <id>'. $feed_info['atom_url'] ."</id>\n";
  print '  <updated>'. _atom_timestamp2w3dtf($last_mod) ."</updated>\n";
  print $output;
  print "</feed>\n";
}

/**
 * @return string
 */
function _atom_timestamp2w3dtf($timestamp) {
  $tz = date("O", $timestamp);
  return date("Y-m-d", $timestamp) .'T'. date("H:i:s", $timestamp) . substr($tz, 0, 3) . ':' . substr($tz, 3, 2);
}

/**
 * Module configuration settings
 *
 * @return array of settings form options or deny access
 */
function atom_settings() {
  if (!user_access('administer atom')) {
    die(drupal_access_denied());
  }
  $form = array();
  for($i=1, $options=array(); $i < 31; $options[$i] = $i, $i+=1);
  $form['atom_feed_entries'] = array(
    '#type' => 'select',
    '#title' => t('Maximum number of entries to include in feeds'),
    '#default_value' => variable_get('atom_feed_entries', 15),
    '#options' => $options
  );
  $form['atom_ad_location'] = array(
    '#type'=> 'radios',
    '#title' => t('Ad unit insertion location'),
    '#default_value' => variable_get('atom_ad_location', 'off'),
    '#options' => array('off' => 'Turned off',
                        'prepend' => 'Prepend',
                        'append' => 'Append'),
    '#description' => t('Insert the ad unit before or after the feed content')
  );
  $form['atom_ad_code'] = array(
    '#type' => 'textarea',
    '#title' => t('Ad unit code'),
    '#default_value' => variable_get('atom_ad_code', ''),
    '#cols' => 40, '#rows' => 10,
    '#description' => t('Ad unit code to insert in atom feed content.')
  );
  return $form;
}

?>
