Commit a8c30ed9 authored by Dries's avatar Dries

- Patch #449718 by alienbrain: node_feed() is now using new node building API.

parent 3d951475
......@@ -97,8 +97,8 @@ function blog_view($node, $teaser) {
* Implementation of hook_node_view.
*/
function blog_node_view($node, $teaser = FALSE) {
if ($node->type == 'blog') {
if (arg(0) != 'blog' || arg(1) != $node->uid) {
if ($node->build_mode != NODE_BUILD_RSS) {
if ($node->type == 'blog' && arg(0) != 'blog' || arg(1) != $node->uid) {
$links['blog_usernames_blog'] = array(
'title' => t("!username's blog", array('!username' => $node->name)),
'href' => "blog/$node->uid",
......
......@@ -715,7 +715,9 @@ function book_node_view($node, $teaser) {
}
}
book_node_view_link($node, $teaser);
if ($node->build_mode != NODE_BUILD_RSS) {
book_node_view_link($node, $teaser);
}
}
/**
......
......@@ -423,7 +423,14 @@ function comment_node_view($node, $teaser) {
$links = array();
if ($node->comment) {
if ($teaser) {
if ($node->build_mode == NODE_BUILD_RSS) {
// Add a comments RSS element which is a URL to the comments of this node.
$node->rss_elements[] = array(
'key' => 'comments',
'value' => url('node/' . $node->nid, array('fragment' => 'comments', 'absolute' => TRUE))
);
}
else if ($teaser) {
// Main page: display the number of comments that have been posted.
if (user_access('access comments')) {
if (!empty($node->comment_count)) {
......@@ -730,18 +737,6 @@ function comment_node_search_result($node) {
return format_plural($comments, '1 comment', '@count comments');
}
/**
* Implementation of hook_node_rss_item().
*/
function comment_node_rss_item($node) {
if ($node->comment != COMMENT_NODE_HIDDEN) {
return array(array('key' => 'comments', 'value' => url('node/' . $node->nid, array('fragment' => 'comments', 'absolute' => TRUE))));
}
else {
return array();
}
}
/**
* Implementation of hook_user_cancel().
*/
......
......@@ -286,28 +286,6 @@ function hook_node_prepare($node) {
function hook_node_prepare_translation($node) {
}
/**
* An RSS feed is being generated.
*
* The module can return properties to be added to the RSS item generated for
* this node. This hook should only be used to add XML elements to the RSS
* feed item itself. See comment_node_rss_item() and upload_node_rss_item()
* for examples.
*
* @param $node
* The node the action is being performed on.
* @return
* Extra information to be added to the RSS item.
*/
function hook_node_rss_item($node) {
if ($node->comment != COMMENT_NODE_HIDDEN) {
return array(array('key' => 'comments', 'value' => url('node/' . $node->nid, array('fragment' => 'comments', 'absolute' => TRUE))));
}
else {
return array();
}
}
/**
* The node is being displayed as a search result.
*
......@@ -401,9 +379,20 @@ function hook_node_validate($node, $form) {
/**
* The node content is being assembled before rendering.
*
* The module may add elements $node->content prior to rendering. This hook
* will be called after hook_view(). The structure of $node->content is a renderable
* array as expected by drupal_render().
* TODO D7 This needs work to clearly explain the different build modes.
*
* The module may add elements to $node->content prior to rendering. This hook
* will be called after hook_view(). The structure of $node->content is a
* renderable array as expected by drupal_render().
*
* When $node->build_mode is NODE_BUILD_RSS modules can also add extra RSS
* elements and namespaces to $node->rss_elements and $node->rss_namespaces
* respectively for the RSS item generated for this node. For details on how
* this is used @see node_feed()
*
* @see taxonomy_node_view()
* @see upload_node_view()
* @see comment_node_view()
*
* @param $node
* The node the action is being performed on.
......
......@@ -1950,70 +1950,38 @@ function node_feed($nids = FALSE, $channel = array()) {
$item_length = variable_get('feed_item_length', 'teaser');
$namespaces = array('xmlns:dc' => 'http://purl.org/dc/elements/1.1/');
$teaser = ($item_length == 'teaser');
// Load all nodes to be rendered.
$nodes = node_load_multiple($nids);
$items = '';
foreach ($nodes as $item) {
$item->build_mode = NODE_BUILD_RSS;
$item->link = url("node/$item->nid", array('absolute' => TRUE));
if ($item_length != 'title') {
$teaser = ($item_length == 'teaser');
// Filter and prepare node teaser
if (node_hook($item, 'view')) {
$item = node_invoke($item, 'view', $teaser, FALSE);
}
else {
$item = node_prepare($item, $teaser);
}
// Allow modules to change $node->content before the node is rendered.
module_invoke_all('node_view', $item, $teaser);
// Set the proper node property, then unset unused $node property so that a
// bad theme can not open a security hole.
$content = drupal_render($item->content);
if ($teaser) {
$item->teaser = $content;
unset($item->body);
}
else {
$item->body = $content;
unset($item->teaser);
}
foreach ($nodes as $node) {
$item_text = '';
$node->build_mode = NODE_BUILD_RSS;
$node->link = url("node/$node->nid", array('absolute' => TRUE));
$node->rss_namespaces = array();
$node->rss_elements = array(
array('key' => 'pubDate', 'value' => gmdate('r', $node->created)),
array('key' => 'dc:creator', 'value' => $node->name),
array('key' => 'guid', 'value' => $node->nid . ' at ' . $base_url, 'attributes' => array('isPermaLink' => 'false'))
);
// Allow modules to modify the fully-built node.
module_invoke_all('node_alter', $item, $teaser, FALSE);
}
// The node gets built and modules add to or modify $node->rss_elements
// and $node->rss_namespaces.
$node = node_build_content($node, $teaser);
// Allow modules to add additional item fields and/or modify $item
$extra = module_invoke_all('node_rss_item', $item);
$extra = array_merge($extra, array(array('key' => 'pubDate', 'value' => gmdate('r', $item->created)), array('key' => 'dc:creator', 'value' => $item->name), array('key' => 'guid', 'value' => $item->nid . ' at ' . $base_url, 'attributes' => array('isPermaLink' => 'false'))));
foreach ($extra as $element) {
if (isset($element['namespace'])) {
$namespaces = array_merge($namespaces, $element['namespace']);
}
if (!empty($node->rss_namespaces)) {
$namespaces = array_merge($namespaces, $node->rss_namespaces);
}
// Prepare the item description
switch ($item_length) {
case 'fulltext':
$item_text = $item->body;
break;
case 'teaser':
$item_text = $item->teaser;
if (!empty($item->readmore)) {
$item_text .= '<p>' . l(t('read more'), 'node/' . $item->nid, array('absolute' => TRUE, 'attributes' => array('target' => '_blank'))) . '</p>';
}
break;
case 'title':
$item_text = '';
break;
if ($item_length != 'title' && !empty($node->content)) {
// We render node contents and force links to be last.
$links = drupal_render($node->content['links']);
$item_text .= drupal_render($node->content) . $links;
}
$items .= format_rss_item($item->title, $item->link, $item_text, $extra);
$items .= format_rss_item($node->title, $node->link, $item_text, $node->rss_elements);
}
$channel_defaults = array(
......
......@@ -658,10 +658,29 @@ class NodeRSSContentTestCase extends DrupalWebTestCase {
// Create a node.
$node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1));
$test_text = t('Extra test data added to node !nid.', array('!nid' => $node->nid));
$this->drupalGet('rss.xml');
$this->assertText($test_text, t('Extra node content appears in RSS feed.'));
// Check that content added in NODE_BUILD_RSS appear in RSS feed.
$rss_only_content = t('Extra data that should appear only in the RSS feed for node !nid.', array('!nid' => $node->nid));
$this->assertText($rss_only_content, t('Node content designated for RSS appear in RSS feed.'));
// Check that content added in build modes other than NODE_BUILD_RSS doesn't
// appear in RSS feed.
$non_rss_content = t('Extra data that should appear everywhere except the RSS feed for node !nid.', array('!nid' => $node->nid));
$this->assertNoText($non_rss_content, t('Node content not designed for RSS doesn\'t appear in RSS feed.'));
// Check that extra RSS elements and namespaces are added to RSS feed.
$test_element = array(
'key' => 'testElement',
'value' => t('Value of testElement RSS element for node !nid.', array('!nid' => $node->nid)),
);
$test_ns = 'xmlns:drupaltest="http://example.com/test-namespace"';
$this->assertRaw(format_xml_elements(array($test_element)), t('Extra RSS elements appear in RSS feed.'));
$this->assertRaw($test_ns, t('Extra namespaces appear in RSS feed.'));
// Check that content added in NODE_BUILD_RSS doesn't appear when viewing node.
$this->drupalGet("node/$node->nid");
$this->assertNoText($rss_only_content, t('Node content designed for RSS doesn\'t appear when viewing node.'));
}
}
......
......@@ -8,11 +8,28 @@
*/
/**
* When the module is enabled, text will be added to all nodes in all build modes.
* Implementation of hook_node_view().
*/
function node_test_node_view($node, $teaser) {
$node->content['node_test_extra_field'] = array(
'#markup' => '<p>' . t('Extra test data added to node !nid.', array('!nid' => $node->nid)) . '</p>',
'#weight' => 10,
);
if ($node->build_mode == NODE_BUILD_RSS) {
// Add RSS elements and namespaces when building the RSS feed.
$node->rss_elements[] = array(
'key' => 'testElement',
'value' => t('Value of testElement RSS element for node !nid.', array('!nid' => $node->nid)),
);
$node->rss_namespaces['xmlns:drupaltest'] = 'http://example.com/test-namespace';
// Add content that should be displayed only in the RSS feed.
$node->content['extra_feed_content'] = array(
'#markup' => '<p>' . t('Extra data that should appear only in the RSS feed for node !nid.', array('!nid' => $node->nid)) . '</p>',
'#weight' => 10,
);
}
if ($node->build_mode != NODE_BUILD_RSS) {
// Add content that should NOT be displayed in the RSS feed.
$node->content['extra_non_feed_content'] = array(
'#markup' => '<p>' . t('Extra data that should appear everywhere except the RSS feed for node !nid.', array('!nid' => $node->nid)) . '</p>',
);
}
}
......@@ -104,20 +104,20 @@ function statistics_perm() {
* Implementation of hook_node_view().
*/
function statistics_node_view($node, $teaser) {
global $id;
$links = array();
if (user_access('view post access counter')) {
$statistics = statistics_get($node->nid);
if ($statistics) {
$links['statistics_counter']['title'] = format_plural($statistics['totalcount'], '1 read', '@count reads');
if ($node->build_mode != NODE_BUILD_RSS) {
$links = array();
if (user_access('view post access counter')) {
$statistics = statistics_get($node->nid);
if ($statistics) {
$links['statistics_counter']['title'] = format_plural($statistics['totalcount'], '1 read', '@count reads');
}
}
}
$node->content['links']['statistics'] = array(
'#type' => 'node_links',
'#value' => $links,
);
$node->content['links']['statistics'] = array(
'#type' => 'node_links',
'#value' => $links,
);
}
}
/**
......
......@@ -39,12 +39,28 @@ function taxonomy_theme() {
* An implementation of hook_node_view().
*/
function taxonomy_node_view($node) {
$links = array();
// If previewing, the terms must be converted to objects first.
if (isset($node->build_mode) && $node->build_mode == NODE_BUILD_PREVIEW) {
$node->taxonomy = taxonomy_preview_terms($node);
if (empty($node->taxonomy)) {
return;
}
if (!empty($node->taxonomy)) {
if ($node->build_mode == NODE_BUILD_RSS) {
// Provide category information for RSS feeds.
foreach ($node->taxonomy as $term) {
$node->rss_elements[] = array(
'key' => 'category',
'value' => $term->name,
'attributes' => array('domain' => url(taxonomy_term_path($term), array('absolute' => TRUE))),
);
}
}
else {
$links = array();
// If previewing, the terms must be converted to objects first.
if ($node->build_mode == NODE_BUILD_PREVIEW) {
$node->taxonomy = taxonomy_preview_terms($node);
}
foreach ($node->taxonomy as $term) {
// During preview the free tagging terms are in an array unlike the
// other terms which are objects. So we have to check if a $term
......@@ -69,13 +85,13 @@ function taxonomy_node_view($node) {
}
}
}
}
$node->content['links']['terms'] = array(
'#type' => 'node_links',
'#value' => $links,
'#sorted' => TRUE,
);
$node->content['links']['terms'] = array(
'#type' => 'node_links',
'#value' => $links,
'#sorted' => TRUE,
);
}
}
/**
......@@ -1589,23 +1605,6 @@ function taxonomy_node_validate($node, $form) {
}
}
/**
* Implementation of hook_node_rss_item().
*
* Provides category information for RSS feeds.
*/
function taxonomy_node_rss_item($node) {
$output = array();
foreach ($node->taxonomy as $term) {
$output[] = array(
'key' => 'category',
'value' => $term->name,
'attributes' => array('domain' => url(taxonomy_term_path($term), array('absolute' => TRUE))),
);
}
return $output;
}
/**
* Implementation of hook_node_update_index().
*/
......
......@@ -62,26 +62,24 @@ function upload_node_links($node, $teaser) {
$links = array();
// Display a link with the number of attachments
if ($teaser && isset($node->files) && user_access('view uploaded files')) {
$num_files = 0;
foreach ($node->files as $file) {
if ($file->list) {
$num_files++;
}
}
if ($num_files) {
$links['upload_attachments'] = array(
'title' => format_plural($num_files, '1 attachment', '@count attachments'),
'href' => "node/$node->nid",
'attributes' => array('title' => t('Read full article to view attachments.')),
'fragment' => 'attachments'
);
$node->content['links']['upload_attachments'] = array(
'#type' => 'node_links',
'#value' => $links,
);
$num_files = 0;
foreach ($node->files as $file) {
if ($file->list) {
$num_files++;
}
}
if ($num_files) {
$links['upload_attachments'] = array(
'title' => format_plural($num_files, '1 attachment', '@count attachments'),
'href' => "node/$node->nid",
'attributes' => array('title' => t('Read full article to view attachments.')),
'fragment' => 'attachments'
);
$node->content['links']['upload_attachments'] = array(
'#type' => 'node_links',
'#value' => $links,
);
}
}
/**
......@@ -341,20 +339,45 @@ function upload_node_load($nodes, $types) {
* Implementation of hook_node_view().
*/
function upload_node_view($node, $teaser) {
if (isset($node->files) && user_access('view uploaded files')) {
// Add the attachments list to node body with a heavy
// weight to ensure they're below other elements.
if (!isset($node->files)) {
return;
}
if (user_access('view uploaded files') && $node->build_mode != NODE_BUILD_RSS) {
if (count($node->files)) {
if (!$teaser) {
// Add the attachments list to node body with a heavy weight to ensure
// they're below other elements.
$node->content['files'] = array(
'#files' => $node->files,
'#theme' => 'upload_attachments',
'#weight' => 50,
);
}
else {
upload_node_links($node, $teaser);
}
}
}
upload_node_links($node, $teaser);
if ($node->build_mode == NODE_BUILD_RSS) {
// Add the first file as an enclosure to the RSS item. RSS allows only one
// enclosure per item. See: http://en.wikipedia.org/wiki/RSS_enclosure
foreach ($node->files as $file) {
if ($file->list) {
break;
}
}
if ($file->list) {
$node->rss_elements[] = array(
'key' => 'enclosure',
'attributes' => array(
'url' => file_create_url($file->filepath),
'length' => $file->filesize,
'type' => $file->filemime
)
);
}
}
}
......@@ -409,35 +432,6 @@ function upload_node_search_result($node) {
return isset($node->files) && is_array($node->files) ? format_plural(count($node->files), '1 attachment', '@count attachments') : NULL;
}
/**
* Implementation of hook_node_rss_item().
*/
function upload_node_rss_item($node) {
if (is_array($node->files)) {
$files = array();
foreach ($node->files as $file) {
if ($file->list) {
$files[] = $file;
}
}
if (count($files) > 0) {
// RSS only allows one enclosure per item
$file = array_shift($files);
return array(
array(
'key' => 'enclosure',
'attributes' => array(
'url' => file_create_url($file->filepath),
'length' => $file->filesize,
'type' => $file->filemime
)
)
);
}
}
return array();
}
/**
* Displays file attachments in table
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment