'admin/settings/feedapi_item', 'title' => t('Node-Item processor'), 'callback' => 'drupal_get_form', 'callback arguments' => array('feedapi_item_admin_settings'), 'type' => MENU_NORMAL_ITEM, 'access' => user_access('administer feedapi'), ); } return $items; } /** * Implementation of hook_menu(). */ function feedapi_item_nodeapi(&$node, $op, $teaser, $page) { if ($op == 'delete') { $result = db_query("SELECT fiid FROM {feedapi_node_item} WHERE nid = %d", $node->nid); if (db_num_rows($result) > 0) { $feed = db_fetch_object($result); feedapi_item_feedapi_item_delete($feed); } } } /** * Implementation of hook_link(). */ function feedapi_item_link($type, $node = NULL, $teaser = FALSE) { if ($type == 'node') { $result = db_query("SELECT item.guid, item.url, feed.fid FROM feedapi_node_feed as feed INNER JOIN feedapi_node_item as item ON item.fid = feed.fid WHERE item.nid = %d", $node->nid); if (db_num_rows($result) > 0) { $feed = db_fetch_object($result); $links['feedapi_article'] = array( 'title' => t('Original article'), 'href' => strlen($feed->url) == 0 ? $feed->guid : $feed->url, ); feedapi_invoke_feedapi("load", $feed); $links['feedapi_original'] = array( 'title' => t('Original site: ') .$feed->title, 'href' => $feed->options->original_url, ); return $links; } } } /** * Implements hook_form_alter(). */ function feedapi_item_form_alter($form_id, &$form) { // Extend the content-type form if ($form_id == 'node_type_form') { $node_type = $form['old_type']['#value']; $form['workflow']['feedapi_item'] = array( '#type' => 'fieldset', '#title' => t('Node-Feed item processor settings'), ); $form['workflow']['feedapi_item']['feedapi_item_promote'] = array( '#type' => 'textfield', '#title' => t('Promoted items'), '#description' => t('The newest N items will be promoted on the front page per feed'), '#default_value' => variable_get('feedapi_item_promote_'. $node_type, 15), ); } // Extend the feed editing form if ($form_id == 'feedapi_edit_page') { $feed = new stdClass(); if (isset($form['fid']['#value'])) { $feed->fid = $form['fid']['#value']; feedapi_invoke_feedapi('load', $feed); if (in_array('feedapi_item', $feed->processors_item)) { $settings = db_fetch_object(db_query("SELECT * FROM {feedapi_node_item_settings} WHERE fid = %d", $feed->fid)); $user_current = user_load(array('uid' => $settings->uid)); if ($user_current->uid == 0) { global $user; $user_current = $user; } $form['processors_settings']['item_content_type'] = array( '#type' => 'select', '#title' => t('The content-type of the items'), '#default_value' => strlen($settings->content_type) > 0 ? $settings->content_type : variable_get('feedapi_item_type', 'story'), '#options' => drupal_map_assoc(array_keys(node_get_types())), '#description' => t('All of the items related to this feed will be created with this type.'), ); $form['processors_settings']['item_node_user'] = array( '#type' => 'textfield', '#title' => t('The author of the item nodes'), '#default_value' => isset($user_current->name) ? $user_current->name : $user->name, '#autocomplete_path' => 'user/autocomplete', ); $form['processors_settings']['item_node_date'] = array( '#type' => 'radios', '#title' => t('Date of the item nodes'), '#options' => array('feed' => t('Comes from the feed'), 'current' => t('The actual server time')), '#default_value' => isset($settings->date) ? $settings->date : variable_get('feedapi_item_node_date', 'feed'), ); } } } } /** * Tell which feed types are compatible with this submodule. * For eg. "XML feed", "FTP", "mailing list" * Implementation of hook_feedapi_type(). * * @return * A string array of compatible types */ function feedapi_item_feedapi_type() { return array("XML feed"); } /** * Create a node from the feed item * Store the relationship between the node and the feed item * Implementation of hook_feedapi_item_save(). * @todo User shouldn't be the user of the time when item is saved. * User should be the owner of the feed. */ function feedapi_item_feedapi_item_save($feed_item, $fid) { // Get our feed specific settings related to items, avoid to query the database all the time when the function is called global $_feedapi_item_feed_settings; if (!isset($_feedapi_item_feed_settings['f'. $fid])) { $settings = db_fetch_array(db_query("SELECT * FROM {feedapi_node_item_settings} WHERE fid = %d", $fid)); $_feedapi_item_feed_settings['f'. $fid] = $settings; } $settings = $_feedapi_item_feed_settings['f'. $fid]; // Construct the node object $node = new stdClass(); $node->type = isset($settings['content_type']) ? $settings['content_type'] : variable_get('feedapi_item_type', 'story'); // Get the default options from the cont $options = variable_get('node_options_'. $node->type, FALSE); if (is_array($options)) { $node->status = in_array('status', $options) ? 1 : 0; $node->promote = in_array('promote', $options) ? 1 : 0; $node->sticky = in_array('sticky', $options) ? 1 : 0; } $node->title = $feed_item->title; global $user; $node->uid = isset($settings['uid']) ? $settings['uid'] : $user->uid; $node->created = (isset($settings['date']) && $settings['date'] == 'feed') ? $feed_item->options->timestamp : time(); $node->body = $feed_item->description; $node->status = 1; if (isset($feed_item->options->teaser)) { $node->teaser = $feed_item->options->teaser; } if (!isset($feed_item->nid)) { node_save($node); $feed_item->nid = $node->nid; db_query("INSERT INTO {feedapi_node_item} (fid, nid, url, timestamp, arrived, guid) VALUES (%d, %d, '%s', %d, %d, '%s')", $fid, $feed_item->nid, $feed_item->options->original_url, $feed_item->options->timestamp, time(), $feed_item->options->guid); } else { $node->nid = $feed_item->nid; node_save($node); db_query("UPDATE {feedapi_node_item} SET url = '%s', timestamp = %d, guid = '%s' WHERE fiid = %d", $feed_item->options->original_url, $feed_item->options->timestamp, $feed_item->options->guid, $feed_item->fiid); } return $feed_item; } /** * Update a node which already assigned to a feed item * Implementation of hook_feedapi_item_update(). */ function feedapi_item_feedapi_item_update($feed_item, $fid) { // Determine which node is assigned to this item if ($feed_item->options->guid) { $node = db_fetch_object(db_query("SELECT nid FROM {feedapi_node_item} WHERE guid = '%s'", $feed_item->options->guid)); } else { $node = db_fetch_object(db_query("SELECT nid FROM {feedapi_node_item} WHERE url = '%s'", $feed_item->options->original_url)); } $feed_item->nid = $node->nid; feedapi_item_feedapi_item_save($feed_item, $fid); return $feed_item; } /** * Delete a node which already assigned to a feed item * Implementation of hook_feedapi_item_delete(). * */ function feedapi_item_feedapi_item_delete($feed_item) { if (isset($feed_item->nid)) { node_delete($feed_item->nid); } db_query("DELETE FROM {feedapi_node_item} WHERE fiid = %d", $feed_item->fiid); } /** * Add to the feed item object some data to identify the * node assigned * Implementation of hook_feedapi_item_load(). * */ function feedapi_item_feedapi_item_load($feed_item) { $item = db_fetch_object(db_query("SELECT * FROM {feedapi_node_item} WHERE fiid = %d", $feed_item->fiid)); $feed_item->fiid = $item->fiid; $feed_item->nid = $item->nid; $feed_item->arrived = $item->arrived; $feed_item->options->original_url = $item->url; $feed_item->options->guid = $item->guid; $feed_item->options->timestamp = $item->timestamp; $content = node_load($feed_item->nid); $feed_item->description = $content->body; $feed_item->title = $content->title; $feed_item->teaser = $content->teaser; return $feed_item; } /** * Implementation of hook_feedapi_item_fetch_items(). * * Construct the basic information (nid, fiid, fid) of all feeds into an array. * * @param $feed * Feed object * @return * The array of feed elements with basic information */ function feedapi_item_feedapi_item_fetch_items($feed) { $result = db_query("SELECT nid, fiid, fid, arrived FROM {feedapi_node_item} WHERE fid = %d", $feed->fid); $items = array(); while ($item = db_fetch_object($result)) { $items[] = $item; } return $items; } /** * Implementation of hook_feedapi_item_unique(). * * Tell if the feed item was seen before or not at the feed * * @param $feed_item * Feed item object * @param $fid * Feed ID * @return * TRUE if the item is new, FALSE if the item is a duplicated one */ function feedapi_item_feedapi_item_unique($feed_item, $fid) { // If the GUID is set, it have to be used to consider two feed items different or not if (isset($feed_item->options->guid)) { $count = db_num_rows(db_query("SELECT fiid FROM {feedapi_node_item} WHERE guid = '%s' AND fid = %d", $feed_item->options->guid, $fid)); if ($count > 0) { return FALSE; } } // Fallback on link else { $count = db_num_rows(db_query("SELECT fiid FROM {feedapi_node_item} WHERE url = '%s'", $feed_item->options->original_url)); if ($count > 0) { return FALSE; } } // Seems that the item is new return TRUE; } /** * Implements hook_feedapi_after_refresh($feed). * Handle the promote N items to the frontpage setting */ function feedapi_item_feedapi_after_refresh($feed) { $type = variable_get('feedapi_item_type', 'story'); $promote = variable_get('feedapi_item_promote_'. $type, 15); $result = db_query("SELECT n.nid FROM {node} n JOIN {feedapi_node_item} fi ON fi.nid = n.nid WHERE fi.fid = %d ORDER BY fi.timestamp DESC", $feed->fid); $to_promote = array(); $to_demote = array(); while ($item = db_fetch_object($result)) { if ($promote-- > 0) { $to_promote[] = $item->nid; } else { $to_demote[] = $item->nid; } } if (count($to_promote) > 0) { db_query("UPDATE {node} SET promote = 1 WHERE nid IN (%s)", implode(',', $to_promote)); } if (count($to_demote) > 0) { db_query("UPDATE {node} SET promote = 0 WHERE nid IN (%s)", implode(',', $to_demote)); } } /** * Implements hook_feedapi_after_update($feed). * Save the options coming from the feed editing */ function feedapi_item_feedapi_after_update($feed) { $user = user_load(array('name' => $feed->item_node_user)); if ($user->uid == 0) { global $user; } if (db_num_rows(db_query("SELECT uid FROM {feedapi_node_item_settings} WHERE fid = %d", $feed->fid)) == 0) { db_query("INSERT INTO {feedapi_node_item_settings} (fid, content_type, uid, date) VALUES (%d, '%s', %d, '%s')", $feed->fid, $feed->item_content_type, $user->uid, $feed->item_node_date); } else { db_query("UPDATE {feedapi_node_item_settings} SET content_type = '%s', uid = %d, date = '%s' WHERE fid = %d", $feed->item_content_type, $user->uid, $feed->item_node_date, $feed->fid); } } /** * Implements hook_feedapi_after_update($feed). */ function feedapi_item_feedapi_after_purge($feed) { db_query("DELETE FROM {feedapi_node_item_settings} WHERE fid = %d", $feed->fid); } /** * Settings: * Content-type of feeds */ function feedapi_item_admin_settings() { $form['feedapi_item_type'] = array( '#type' => 'select', '#title' => t('Item content-type'), '#default_value' => variable_get('feedapi_item_type', 'story'), '#options' => drupal_map_assoc(array_keys(node_get_types())), '#description' => t('The default type of the feed items.') ); $form['processors_settings']['feedapi_item_node_date'] = array( '#type' => 'radios', '#title' => t('Date of the item nodes'), '#options' => array('feed' => t('Comes from the feed'), 'current' => t('The current server time')), '#default_value' => variable_get('feedapi_item_node_date', 'feed'), ); return system_settings_form($form); }