Index: drupal/includes/common.inc
diff -u drupal/includes/common.inc:1.1.2.3 drupal/includes/common.inc:1.1.2.3.2.4
--- drupal/includes/common.inc:1.1.2.3 Mon Apr 5 13:09:44 2004
+++ drupal/includes/common.inc Sun Apr 11 20:02:23 2004
@@ -746,22 +746,125 @@
return $output;
}
-function format_rss_item($title, $link, $description, $args = array()) {
- // arbitrary elements may be added using the $args associative array
-
- $output = "\n";
- $output .= " ". drupal_specialchars(strip_tags($title)) ."\n";
- $output .= " ". drupal_specialchars(strip_tags($link)) ."\n";
- $output .= " ". drupal_specialchars(check_output($description)) ."\n";
- foreach ($args as $key => $value) {
- $output .= "<$key>". drupal_specialchars(strip_tags($value)) ."$key>";
+function format_rss_item(&$namespaces, $node, $version) {
+ $xml['item']->contents['title']->contents = drupal_specialchars(strip_tags($node->title));
+ $xml['item']->contents['link']->contents = drupal_specialchars(strip_tags(url("node/view/$node->nid", NULL, NULL, 1)));
+ $xml['item']->contents['description']->contents = drupal_specialchars(check_output($node->teaser ? $node->teaser : $node->body));
+ $xml['item']->contents['pubDate']->contents = date('r', $node->changed);
+
+ foreach (module_list() as $name) {
+ $function = $name ."_rss_item";
+ if (function_exists($function)) {
+ $function($xml['item']->contents, $namespaces, $node, $version);
+ }
}
- $output .= "\n";
+
+ return format_xml($xml);
+}
+/**
+ * Formats an associative array of XML tags as an xml document. Each array key
+ * is the name (including abbreviated namespace) of a top level tag. The array
+ * values are objects containing the attributes and contents of the xml tag.
+ * The object format is described in detail in the documentation for the
+ * format_xml_tag function.
+ *
+ * @param $xml An associative array of tag name => xml tag as object
+ * @return String of indented XML
+ */
+function format_xml($xml) {
+ foreach ($xml as $tag => $content) {
+ $output .= format_xml_tag($content, $tag);
+ }
return $output;
}
/**
+ * An xml tag contains two important things, attributes and contents, these are
+ * the two variables in an xml tag object as processed by this function. Either
+ * or both may be omitted if applicable.
+ *
+ * $xml->attributes is an associative array of attribute names as keys with
+ * attribute values as values.
+ * $xml->contents can either be a string or array of tags. If the tag only
+ * contains a string then use a string. If it is an array of tags, then
+ * contents will be an associative array with tag names as keys. The values of
+ * the associative array are other objects constructed in the same way if there
+ * is only one tag with that name; if there are multiples then the value will
+ * be a simple array of objects.
+ *
+ * This function makes no attempt to assure valid xml output, if the input is
+ * not well formed, then the output won't be well formed either. Use proper
+ * entity coding where necessary, especially for angle brackets, ampersands,
+ * and double quotes.
+ *
+ * @param $xml An object structured to represent an XML tag as described above.
+ * @param $name The name of the represented XML tag.
+ * @param $indent The base indentation of the tag as a string of whitespace.
+ * @return A string containing the XML tag in XML format.
+ */
+function format_xml_tag($xml, $name, $indent = '') {
+ $result = $indent .'<'. $name;
+ if ($xml->attributes) {
+ foreach ($xml->attributes as $attribute => $value) {
+ $result .= ' '. $attribute .'="'. $value .'"';
+ }
+ }
+ if (is_array($xml->contents)) {
+ $result .= ">\n";
+ foreach ($xml->contents as $tag => $content) {
+ if (is_array($content)) {
+ foreach($content as $content_value) {
+ $result .= format_xml_tag($content_value, $tag, ' '. $indent);
+ }
+ }
+ else {
+ $result .= format_xml_tag($content, $tag, ' '. $indent);
+ }
+ }
+ $result .= $indent .''. $name .'>';
+ }
+ else if ($xml->contents) {
+ $result .= '>'. $xml->contents .''. $name .'>';
+ }
+ else {
+ $result .= ' />';
+ }
+ return $result ."\n";
+}
+
+/**
+ * Formats a date accorfing to the W3C pecification at
+ * http://www.w3.org/TR/NOTE-datetime
+ *
+ * @param $timestamp The exact date to format.
+ * @param $precision either 'year', 'month', 'day', or 'time'.
+ * @param $timezone Timezone offset in seconds in case the user timezone
+ * should not be used.
+ * @return The W3C formatted date with the requested percision.
+ */
+function format_w3c_date($timestamp, $precision = 'time', $timzone = NULL) {
+ if ($timezone === NULL) {
+ global $user;
+ $timezone = $user->uid ? $user->timezone : variable_get('date_default_timezone', 0);
+ }
+ $timestamp += $timezone;
+
+ switch ($precision) {
+ case 'time':
+ $result = 'T'. gmdate('H', $timestamp) .':'. gmdate('i', $timestamp) . sprintf('%s%02d:%02d', ($timezone < 0 ? '-' : '+'), abs($timezone / 3600), abs($timezone % 3600) / 60) . $result;
+ case 'day':
+ $result = '-'. gmdate('d', $timestamp) . $result;
+ case 'month':
+ $result = '-'. gmdate('m', $timestamp) . $result;
+ case 'year':
+ $result = gmdate('Y', $timestamp) . $result;
+ }
+
+ return $result;
+}
+
+/**
* Formats a string with a count of items so that the string is pluralized
* correctly. format_plural calls t() by itself, make sure not to pass already
* localized strings to it.
Index: drupal/modules/node.module
diff -u drupal/modules/node.module:1.1.2.4 drupal/modules/node.module:1.1.2.4.2.4
--- drupal/modules/node.module:1.1.2.4 Wed Apr 7 09:25:26 2004
+++ drupal/modules/node.module Mon Apr 12 12:55:37 2004
@@ -1002,18 +1002,8 @@
$nodes = db_query_range('SELECT nid FROM {node} WHERE promote = 1 AND status = 1 ORDER BY created DESC', 0, 15);
}
- while ($node = db_fetch_object($nodes)) {
- /*
- ** Load the specified node:
- */
-
- $item = node_load(array('nid' => $node->nid));
- $link = url("node/view/$node->nid", NULL, NULL, 1);
- $items .= format_rss_item($item->title, $link, ($item->teaser ? $item->teaser : $item->body), array('pubDate' => date('r', $item->changed)));
- }
-
$channel_defaults = array(
- 'version' => '0.92',
+ 'version' => '2.0',
'title' => variable_get('site_name', 'drupal') .' - '. variable_get('site_slogan', ''),
'link' => $base_url,
'description' => variable_get('site_mission', ''),
@@ -1021,9 +1011,18 @@
);
$channel = array_merge($channel_defaults, $channel);
+ $namespaces = array();
+ while ($node = db_fetch_object($nodes)) {
+ $items .= format_rss_item($namespaces, node_load(array('nid' => $node->nid)), $channel["version"]);
+ }
+
$output = "\n";
$output .= "]>\n";
- $output .= "\n";
+ $output .= " $url) {
+ $output .= " xmlns:$ns=\"$url\"";
+ }
+ $output .= ">\n";
$output .= format_rss_channel($channel['title'], $channel['link'], $channel['description'], $items, $channel['language']);
$output .= "\n";