Index: feedapi.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/feedapi/feedapi.module,v retrieving revision 1.23.2.100 diff -u -r1.23.2.100 feedapi.module --- feedapi.module 11 Dec 2007 21:59:10 -0000 1.23.2.100 +++ feedapi.module 13 Dec 2007 21:30:48 -0000 @@ -49,24 +49,22 @@ $items[] = array( 'path' => 'admin/content/feed/import_opml', 'title' => t('Import OPML'), - 'type' => MENU_NORMAL_ITEM, 'access' => user_access('administer feedapi'), 'callback' => 'drupal_get_form', 'callback arguments' => array('feedapi_import_feeds_form'), ); $items[] = array( 'path' => 'admin/content/feed/export_opml', - 'title' => t('Import OPML'), - 'type' => MENU_CALLBACK, + 'title' => t('Export all feeds as OPML'), 'access' => user_access('administer feedapi'), 'callback' => 'drupal_get_form', 'callback arguments' => array('_feedapi_export_opml'), ); - $items[] = array('path' => 'admin/settings/feedapi', + $items[] = array( + 'path' => 'admin/settings/feedapi', 'title' => t('FeedAPI settings'), 'callback' => 'drupal_get_form', 'callback arguments' => array('feedapi_admin_settings'), - 'type' => MENU_NORMAL_ITEM, 'access' => user_access('administer feedapi'), ); } @@ -75,14 +73,16 @@ if (isset($node->feed)) { global $user; $own_feed = $node->uid == $user->uid && user_access('edit own '. $node->type . ' content') ? TRUE : FALSE; - $items[] = array('path' => 'node/'. $node->nid. '/refresh', + $items[] = array( + 'path' => 'node/'. $node->nid. '/refresh', 'title' => t('Refresh'), 'callback' => 'feedapi_refresh', 'callback arguments' => array($node, 'node/'. $node->nid), 'type' => MENU_LOCAL_TASK, 'access' => (user_access('administer feedapi') || $own_feed), ); - $items[] = array('path' => 'node/'. $node->nid. '/purge', + $items[] = array( + 'path' => 'node/'. $node->nid. '/purge', 'title' => t('Remove items'), 'callback' => 'feedapi_invoke_feedapi', 'callback arguments' => array("purge", $node->feed, 'items'), @@ -115,7 +115,6 @@ $node_type_settings = _feedapi_get_settings(array('node_type' => $node->type)); $node->feed->parsers = _feedapi_format_settings($node_type_settings, 'parsers'); $node->feed->processors = _feedapi_format_settings($node_type_settings, 'processors'); - $node->feed->nid = $node->nid; } break; case 'delete': @@ -132,12 +131,7 @@ case 'submit': // Todo: the first case essentially copies the entire feed array from feedapi to feed. // Figure out a way how to save this step. - if ($node->feedapi_feed_object) { - $node->feed = $node->feedapi_feed_object; - } - else { - $node->feed = _feedapi_build_feed_object($node->type, $node->feedapi['feedapi_url']); - } + $node->feed = isset($node->feedapi_feed_object) ? $node->feedapi_feed_object : _feedapi_build_feed_object($node->type, $node->feedapi['feedapi_url']); break; } } @@ -147,10 +141,9 @@ * Implementation of hook_node_type(). */ function feedapi_node_type($op, $info) { - switch ($op){ + switch ($op) { case 'delete': variable_del('feedapi_settings_'. $info->type); - // Todo: find out, why and where there is still feedapi_$info->type being stored. variable_del('feedapi_'. $info->type); break; case 'update': @@ -178,14 +171,13 @@ foreach ($names as $type => $name) { $blocks[$type]['info'] = t('FeedAPI: Quick create !preset', array('!preset' => $name)); } - return $blocks; case 'view': if (node_access('create', $delta)) { - $block['subject'] = t('Create !preset', array('!preset' => $names[$delta])); - $block['content'] = drupal_get_form('feedapi_simplified_form', $delta); + $blocks['subject'] = t('Create !preset', array('!preset' => $names[$delta])); + $blocks['content'] = drupal_get_form('feedapi_simplified_form', $delta); } - return $block; } + return $blocks; } /** @@ -214,19 +206,16 @@ * Implementation of hook_simpletest(). */ function feedapi_simpletest() { - $tests = file_scan_directory(drupal_get_path('module', 'feedapi'), '\.test'); - return array_keys($tests); + return array_keys(file_scan_directory(drupal_get_path('module', 'feedapi'), '\.test')); } /** - * Do various things with feed. Handle the core data and call the - * underyling modules (parsers/processors) too. - * TODO: Clean up this function, break it in smaller pieces that are - * easier to handle. + * Call the proper private function to handle feed operations * * @param $op * "load" Load the feed items basic data into the $feed->items[] * "refresh" Re-download the feed and process newly arrived item + * "purge" Delete all the feed items * * @param $feed * A feed object. If only the ID is known, you should pass something like this: $feed->nid = X @@ -245,122 +234,8 @@ $feed = $node->feed; } _feedapi_sanitize_processors($feed); - switch ($op) { - case 'load': - $feed->items = array(); - foreach ($feed->processors as $processor) { - $items = module_invoke($processor, 'feedapi_item', 'fetch', $feed); - if (is_array($items)) { - foreach ($items as $item) { - $feed->items[] = $item; - } - } - } - break; - - case 'refresh': - timer_start('feedapi_'. $feed->nid); - $cron = $param; - if (!is_array($feed->processors) || count($feed->processors) == 0) { - if (!$cron) { - drupal_set_message(t("No processors specified for URL %url. Could not refresh.", array('%url' => $feed->url)), "error"); - drupal_goto('node/'. $feed->nid); - } - return; - } - // Force the processors to delete old items and determine the max. create elements - $refresh = feedapi_expire($feed, $cron === TRUE ? FALSE : TRUE); - if ($refresh == FALSE) { - return; - } - $nid = $feed->nid; - // Force non-caching mode if the feed is only processed half-done. - $feed = _feedapi_call_parsers($feed, $feed->parsers, $feed->half_done ? FALSE : TRUE); - if (($feed === FALSE) || (!is_array($feed->items))) { - // Refresh the Last refresh field at all the cases - db_query("UPDATE {feedapi} SET checked = %d, half_done = %d WHERE nid = %d", time(), FALSE, $nid); - if (!$cron) { - drupal_set_message(t('Could not refresh feed.')); - } - return; - } - - $items = array_reverse($feed->items); - $updated = 0; - $new = 0; - $half_done = FALSE; - $settings = _feedapi_get_settings(array('nid' => $feed->nid)); - // Walk through the items - foreach ($items as $item) { - // Call each item parser - $is_updated = FALSE; - $is_new = FALSE; - foreach ($feed->processors as $processor) { - if (!module_invoke($processor, 'feedapi_item', 'unique', $item, $feed->nid, $feed->settings['processors'][$processor])) { - if ($settings['update_existing'] == TRUE) { - module_invoke($processor, 'feedapi_item', 'update', $item, $feed->nid, $feed->settings['processors'][$processor]); - $is_updated = TRUE; - } - } - else { - - // if the item is already expired then do nothing - $diff = abs(time() - (isset($item->options->timestamp) ? $item->options->timestamp : time())); - $items_delete = $settings['items_delete']; - if ($diff > $items_delete && ($items_delete > FEEDAPI_NEVER_DELETE_OLD)) { - break; - } - - module_invoke($processor, 'feedapi_item', 'save', $item, $feed->nid, $feed->settings['processors'][$processor]); - $is_new = TRUE; - } - } - $new = $is_new ? $new + 1 : $new; - $updated = ($is_updated && !$is_new) ? $updated + 1 : $updated; - // decision on time. If the exec time is greather than the user-set percentage of php max execution time - if ($cron && ((timer_read('feedapi_cron') / 1000) > ((variable_get('feedapi_cron_percentage', 15) / 100) * ini_get('max_execution_time')))) { - $timeout = FEEDAPI_TIMEOUT; - $half_done = ($new + $updated) == count($items) ? FALSE : TRUE; - break; - } - } - foreach (module_implements('feedapi_after_refresh') as $module) { - $func = $module. '_feedapi_after_refresh'; - $func($feed); - } - if ($new > 0) { - $feed->statistics['update_times'] = _feedapi_queue($feed->statistics['update_times'], time()); - $feed->statistics['new'] = _feedapi_queue($feed->statistics['new'], $new); - $feed->statistics['download_num'] = _feedapi_queue($feed->statistics['download_num'], count($items)); - $feed->statistics['process_time'] = _feedapi_queue($feed->statistics['process_time'], timer_read('feedapi_'. $feed->nid)); - } - db_query("UPDATE {feedapi} SET checked = %d, statistics = '%s', half_done = %d WHERE nid = %d", time(), serialize($feed->statistics), $half_done, $feed->nid); - if (!$cron) { - drupal_set_message(t("%new new item(s) were saved. %updated existing item(s) were updated.", array("%new" => $new, "%updated" => $updated))); - } - if ($timeout) { - return $timeout; - } - break; - - case 'purge': - $node = node_load($feed->nid); - if ($param == 'items') { - return drupal_get_form('feedapi_purge_confirm', $node); - } - feedapi_invoke_feedapi('load', $feed); - - // Delete items from the processors - foreach ($feed->items as $item) { - foreach($feed->processors as $processor) { - // FIXME: it's possible now to accidentally delete an item from another processor - module_invoke($processor, 'feedapi_item', 'delete', $item, $feed->settings['processors'][$processor]); - } - } - if ($param == 'items_confirmed') { - drupal_set_message(t('!count feed items have been deleted successfully from the feed.', array('!count' => count($feed->items)))); - } - break; + if (in_array($op, array('load', 'refresh', 'purge'))) { + return call_user_func('_feedapi_'. $op, $feed, $param); } } @@ -392,8 +267,6 @@ * OPML Feed import form, also allows setting defaults to be applied to each feed */ function feedapi_import_feeds_form() { - global $user; - $form['#attributes'] = array('enctype' => 'multipart/form-data'); $form['opml'] = array( '#type' => 'file', '#title' => t('OPML File'), @@ -411,17 +284,10 @@ '#title' => t('Feed Type'), '#description' => t("The type of feed you would like to associate this import with."), '#options' => $feed_types, - '#default_value' => '', - '#size' => 1, '#required' => TRUE, ); - $node = new stdClass(); - $node->uid = $user->uid; - $form['#node'] = $node; - $form['#method'] = 'post'; $form['#attributes']['enctype'] = 'multipart/form-data'; $form['submit'] = array('#type' => 'submit', '#value' => 'Submit'); - if (module_exists('og')) { og_form_add_og_audience('feedapi_import_feeds_form', $form); } @@ -442,7 +308,6 @@ else { drupal_set_message(t('Feed list could not be imported. Please check that this is a valid OPML file.'), 'error'); } - } else { drupal_set_message(t('Data could not be retrieved, invalid or empty file.'), 'error'); @@ -462,13 +327,12 @@ */ function feedapi_expire($feed, $force) { $settings = _feedapi_get_settings(array('nid' => $feed->nid)); - $feed->items_delete = $settings['items_delete']; $needs_refresh = time() - $feed->checked > $feed->refresh; - if (is_array($feed->items) && ($needs_refresh || $force) && $feed->items_delete > FEEDAPI_NEVER_DELETE_OLD) { + if (is_array($feed->items) && ($needs_refresh || $force) && $settings['items_delete'] > FEEDAPI_NEVER_DELETE_OLD) { foreach ($feed->items as $item) { if (isset($item->arrived) || isset($item->timestamp)) { $diff = abs(time() - (isset($item->timestamp) ? $item->timestamp : $item->timestamp)); - if ($diff > $feed->items_delete) { + if ($diff > $settings['items_delete']) { foreach($feed->processors as $processor) { module_invoke($processor, 'feedapi_item', 'delete', $item, $feed->nid); } @@ -476,10 +340,7 @@ } } } - if ($needs_refresh == FALSE && $force == FALSE) { - return FALSE; - } - return TRUE; + return ($needs_refresh == FALSE && $force == FALSE) ? FALSE : TRUE; } /** @@ -661,53 +522,32 @@ // Which parsers / processors are enabled is a per content-type setting. $node_type_settings = _feedapi_get_settings(array('node_type' => $form['type']['#value'])); // retrieve forms. - $suitable_parsers = module_implements('feedapi_feed', TRUE); - foreach ($suitable_parsers as $module) { - if ($node_type_settings['parsers'][$module]['enabled']) { - $result = array(); - $result = module_invoke($module, 'feedapi_settings_form', 'parsers'); - if (is_array($result)) { - $result['#weight'] = $node_type_settings['parsers'][$module]['weight']; - $form['feedapi']['parsers'][$module] = $result; - $form['feedapi']['parsers'][$module]['#type'] = 'fieldset'; - $form['feedapi']['parsers'][$module]['#title'] = feedapi_get_natural_name($module); - $form['feedapi']['parsers'][$module]['#collapsible'] = TRUE; - $form['feedapi']['parsers'][$module]['#collapsed'] = FALSE; - $form['feedapi']['parsers'][$module]['#tree'] = TRUE; + + foreach (array("parsers" => "feedapi_feed", "processors" => "feedapi_item") as $type => $requirement) { + $suitable_handlers = module_implements($requirement, TRUE); + foreach ($suitable_handlers as $module) { + if ($node_type_settings[$type][$module]['enabled']) { + $result = array(); + $result = module_invoke($module, 'feedapi_settings_form', $type); + if (is_array($result)) { + $result['#weight'] = $node_type_settings[$type][$module]['weight']; + $form['feedapi'][$type][$module] = $result; + $form['feedapi'][$type][$module]['#type'] = 'fieldset'; + $form['feedapi'][$type][$module]['#title'] = feedapi_get_natural_name($module); + $form['feedapi'][$type][$module]['#collapsible'] = TRUE; + $form['feedapi'][$type][$module]['#collapsed'] = FALSE; + $form['feedapi'][$type][$module]['#tree'] = TRUE; + } } } - } - if ($form['feedapi']['parsers']) { - $form['feedapi']['parsers']['#type'] = 'fieldset'; - $form['feedapi']['parsers']['#title'] = t('Parsers'); - $form['feedapi']['parsers']['#collapsible'] = TRUE; - $form['feedapi']['parsers']['#collapsed'] = TRUE; - $form['feedapi']['parsers']['#tree'] = TRUE; - } - - $suitable_processors = module_implements('feedapi_item', TRUE); - foreach ($suitable_processors as $module) { - if ($node_type_settings['processors'][$module]['enabled']) { - $result = array(); - $result = module_invoke($module, 'feedapi_settings_form', 'processors'); - if (is_array($result)) { - $result['#weight'] = $node_type_settings['processors'][$module]['weight']; - $form['feedapi']['processors'][$module] = $result; - $form['feedapi']['processors'][$module]['#type'] = 'fieldset'; - $form['feedapi']['processors'][$module]['#title'] = feedapi_get_natural_name($module); - $form['feedapi']['processors'][$module]['#collapsible'] = TRUE; - $form['feedapi']['processors'][$module]['#collapsed'] = FALSE; - $form['feedapi']['processors'][$module]['#tree'] = TRUE; - } + if (isset($form['feedapi'][$type])) { + $form['feedapi'][$type]['#type'] = 'fieldset'; + $form['feedapi'][$type]['#title'] = t('Parsers'); + $form['feedapi'][$type]['#collapsible'] = TRUE; + $form['feedapi'][$type]['#collapsed'] = TRUE; + $form['feedapi'][$type]['#tree'] = TRUE; } } - if ($form['feedapi']['processors']) { - $form['feedapi']['processors']['#type'] = 'fieldset'; - $form['feedapi']['processors']['#title'] = t('Processors'); - $form['feedapi']['processors']['#collapsible'] = TRUE; - $form['feedapi']['processors']['#collapsed'] = TRUE; - $form['feedapi']['processors']['#tree'] = TRUE; - } } // If we are on a node form, get per node settings and populate form. if (!$settings = _feedapi_get_settings(array('nid' => $form['#node']->nid, 'node_type' => $form['type']['#value']))) { @@ -719,7 +559,6 @@ /** * Implementation of hook_feedapi_settings_form(). - * FeedAPI specific settings. */ function feedapi_feedapi_settings_form($type) { if ($type == 'general') { @@ -753,10 +592,9 @@ function feedapi_cron() { $result = db_query("SELECT nid FROM {feedapi} ORDER BY checked ASC"); timer_start('feedapi_cron'); - while ($feed = db_fetch_object($result, $row++)) { + while ($feed = db_fetch_object($result)) { feedapi_invoke_feedapi('load', $feed); - $timeout = feedapi_invoke_feedapi('refresh', $feed, TRUE); - if ($timeout == FEEDAPI_TIMEOUT) { + if (FEEDAPI_TIMEOUT == feedapi_invoke_feedapi('refresh', $feed, TRUE)) { break; } } @@ -815,7 +653,6 @@ "Averages over the last @count refreshes." ); $output .= theme('table', $header, $rows); - $output .= l(t('Export site feeds as OPML'), 'admin/content/feed/export_opml'); $output .= theme('pager', 0, 50); return $output; } @@ -838,7 +675,7 @@ ); $form['submit'] = array( '#type' => 'submit', - '#value' => t('Submit'), + '#value' => t('Add'), ); return $form; } @@ -877,8 +714,7 @@ } /** - * Settings: - * Allowed HTML tags, number of feeds refreshed in one round + * Settings: allowed HTML tags, number of feeds refreshed in one round */ function feedapi_admin_settings() { $form['feedapi_allowed_html_tags'] = array( @@ -958,26 +794,6 @@ } /** - * Update a feedapi node URL. - * This function could be expanded to allow more updates than the URL. - * @param $nid - * node-id of node to be updated. - * @param $url - * string - new URL. - * @param $title - * string - optional new title. - * @return - * Updated node. - */ -function feedapi_update_node($nid, $url, $title = NULL) { - $node = node_load($nid); - $node->feed->url = $url; - $node->title = $title ? $title : $node->title; - node_save($node); - return $node; -} - -/** * Load node by URL. * @param $args * Currently only supported $args['url] - URL string. @@ -994,13 +810,11 @@ /** * Refresh a feed node (= run enabled processors on it). * @param $node - * A node object with a $node->feed object. + * A node object with a $node->feed object. * @param $destination_path - * If a destination path is given, function redirects to this destination. - * @param $cron - * If TRUE, function will be silent (no screen messages). + * If a destination path is given, function redirects to this destination. */ -function feedapi_refresh($node, $destination_path = NULL, $cron = FALSE) { +function feedapi_refresh($node, $destination_path = NULL) { feedapi_invoke_feedapi('refresh', $node->feed, $cron); if ($destination_path) { drupal_goto($destination_path); @@ -1061,12 +875,12 @@ db_query("UPDATE {feedapi} SET url = '%s', feed_type = '%s', processors = '%s', parsers = '%s', link = '%s' WHERE nid = %d", - $node->feed->url, - $node->feed->feed_type, - serialize($node->feed->processors), - serialize($node->feed->parsers), - $node->feed->options->link, - $node->nid + $node->feed->url, + $node->feed->feed_type, + serialize($node->feed->processors), + serialize($node->feed->parsers), + $node->feed->options->link, + $node->nid ); // Store add on module's settings if user has permission to do so. if (user_access('advanced feedapi options')) { @@ -1095,6 +909,7 @@ $parser_primary = array_shift($parsers); $parsers_secondary = $parsers; if (module_exists($parser_primary)) { + $feed->feed_type = module_invoke($parser_primary, 'feedapi_feed', 'compatible', $feed); $parser_output = module_invoke($parser_primary, 'feedapi_feed', 'parse', $feed, $cache); if ($parser_output === FALSE && $cache) { return $parser_output; @@ -1163,9 +978,9 @@ * If parser or processor is passed in, this function determines wether given * parser or processor is enabled for given node type. * @param $node_type - * A Drupal node type. + * A Drupal node type. * @param $parser_or_processor - * A parser or processor - pass in by module name. + * A parser or processor - pass in by module name. * @return TRUE if enabled, FALSE if not. */ function feedapi_enabled($node_type, $parser_or_processor = '') { @@ -1182,6 +997,131 @@ } /** + * Put a list of feed items into the feed object from the processors + */ +function _feedapi_load(&$feed, $param) { + $feed->items = array(); + foreach ($feed->processors as $processor) { + $items = module_invoke($processor, 'feedapi_item', 'fetch', $feed); + if (is_array($items)) { + foreach ($items as $item) { + $feed->items[] = $item; + } + } + } +} + +/** + * Refresh the feed, call the proper parsers and processors' hooks + */ +function _feedapi_refresh(&$feed, $param) { + timer_start('feedapi_'. $feed->nid); + $cron = $param; + if (!is_array($feed->processors) || count($feed->processors) == 0) { + if (!$cron) { + drupal_set_message(t("No processors specified for URL %url. Could not refresh.", array('%url' => $feed->url)), "error"); + drupal_goto('node/'. $feed->nid); + } + return; + } + // Force the processors to delete old items and determine the max. create elements + $refresh = feedapi_expire($feed, $cron === TRUE ? FALSE : TRUE); + if ($refresh == FALSE) { + return; + } + $nid = $feed->nid; + // Force non-caching mode if the feed is only processed half-done. + $feed = _feedapi_call_parsers($feed, $feed->parsers, $feed->half_done ? FALSE : TRUE); + if (($feed === FALSE) || (!is_array($feed->items))) { + // Refresh the Last refresh field at all the cases + db_query("UPDATE {feedapi} SET checked = %d, half_done = %d WHERE nid = %d", time(), FALSE, $nid); + if (!$cron) { + drupal_set_message(t('Could not refresh feed.')); + } + return; + } + + $items = array_reverse($feed->items); + $updated = 0; + $new = 0; + $half_done = FALSE; + $settings = _feedapi_get_settings(array('nid' => $feed->nid)); + // Walk through the items + foreach ($items as $item) { + // Call each item parser + $is_updated = FALSE; + $is_new = FALSE; + foreach ($feed->processors as $processor) { + if (!module_invoke($processor, 'feedapi_item', 'unique', $item, $feed->nid, $feed->settings['processors'][$processor])) { + if ($settings['update_existing'] == TRUE) { + module_invoke($processor, 'feedapi_item', 'update', $item, $feed->nid, $feed->settings['processors'][$processor]); + $is_updated = TRUE; + } + } + else { + + // if the item is already expired then do nothing + $diff = abs(time() - (isset($item->options->timestamp) ? $item->options->timestamp : time())); + $items_delete = $settings['items_delete']; + if ($diff > $items_delete && ($items_delete > FEEDAPI_NEVER_DELETE_OLD)) { + break; + } + + module_invoke($processor, 'feedapi_item', 'save', $item, $feed->nid, $feed->settings['processors'][$processor]); + $is_new = TRUE; + } + } + $new = $is_new ? $new + 1 : $new; + $updated = ($is_updated && !$is_new) ? $updated + 1 : $updated; + // decision on time. If the exec time is greather than the user-set percentage of php max execution time + if ($cron && ((timer_read('feedapi_cron') / 1000) > ((variable_get('feedapi_cron_percentage', 15) / 100) * ini_get('max_execution_time')))) { + $timeout = FEEDAPI_TIMEOUT; + $half_done = ($new + $updated) == count($items) ? FALSE : TRUE; + break; + } + } + foreach (module_implements('feedapi_after_refresh') as $module) { + $func = $module. '_feedapi_after_refresh'; + $func($feed); + } + if ($new > 0) { + $feed->statistics['update_times'] = _feedapi_queue($feed->statistics['update_times'], time()); + $feed->statistics['new'] = _feedapi_queue($feed->statistics['new'], $new); + $feed->statistics['download_num'] = _feedapi_queue($feed->statistics['download_num'], count($items)); + $feed->statistics['process_time'] = _feedapi_queue($feed->statistics['process_time'], timer_read('feedapi_'. $feed->nid)); + } + db_query("UPDATE {feedapi} SET checked = %d, statistics = '%s', half_done = %d WHERE nid = %d", time(), serialize($feed->statistics), $half_done, $feed->nid); + if (!$cron) { + drupal_set_message(t("%new new item(s) were saved. %updated existing item(s) were updated.", array("%new" => $new, "%updated" => $updated))); + } + if ($timeout) { + return $timeout; + } +} + +/** + * Delete all feed items of a feed. + */ +function _feedapi_purge(&$feed, $param) { + $node = node_load($feed->nid); + if ($param == 'items') { + return drupal_get_form('feedapi_purge_confirm', $node); + } + feedapi_invoke_feedapi('load', $feed); + + // Delete items from the processors + foreach ($feed->items as $item) { + foreach($feed->processors as $processor) { + // FIXME: it's possible now to accidentally delete an item from another processor + module_invoke($processor, 'feedapi_item', 'delete', $item, $feed->settings['processors'][$processor]); + } + } + if ($param == 'items_confirmed') { + drupal_set_message(t('!count feed items have been deleted successfully from the feed.', array('!count' => count($feed->items)))); + } +} + +/** * Builds feed object ready to be sticked onto node. */ function _feedapi_build_feed_object($node_type, $url) { @@ -1190,14 +1130,6 @@ $node_type_settings = _feedapi_get_settings(array('node_type' => $node_type)); $feed->processors = _feedapi_format_settings($node_type_settings, 'processors'); $feed->parsers = _feedapi_format_settings($node_type_settings, 'parsers'); - $feed->feed_type = "XML feed"; - /* - Todo - move assign procedure to 'refresh'. Decide what to do with $feed->feed_type = "XML feed" - $assigned = _feedapi_assign_parser_processor($feed->url, $node_type_settings); - $feed->processors = $assigned['processors']; - $feed->parsers = $assigned['parsers']; - $feed->feed_type = $assigned['type']; - */ if ($feed->url) { $feed = _feedapi_call_parsers($feed, $feed->parsers, FALSE); } @@ -1240,7 +1172,7 @@ * parsers/processors, use per node settings to override their * configuration, this allows us a more predictable * presets/settings behaviour. See d. o. #191692 - * Todo: add caching. + * Todo: add caching. * Watch out: cache permutations of node_type or node_type+nid or nid. * Watch out: changes within page load likely. */ @@ -1291,67 +1223,8 @@ } /** - * Auto-detect one possible parser and one feed and item processor to the given URL - * It follows the order of the modules from the module's settings page. - */ -function _feedapi_assign_parser_processor($url, $node_type_settings) { - $parsers = module_implements('feedapi_feed', TRUE); - // Get the parsers' weight - $sorted_parsers = array(); - foreach ($parsers as $parser) { - if ($node_type_settings['parsers'][$parser]['enabled']) { - $sorted_parsers[$node_type_settings['parsers'][$parser]['weight']][] = $parser; - } - } - $success = FALSE; - $keys = array_keys($sorted_parsers); - if (count($keys) > 0) { - $low = min($keys); - $max = max($keys); - // Call the ordered parsers to find all the compatible - $parsers = array(); - $parsers['secondary'] = array(); - for ($i = $low; $i <= $max; $i++) { - if (isset($sorted_parsers[$i])) { - foreach ($sorted_parsers[$i] as $parser) { - $type = module_invoke($parser, 'feedapi_feed', 'compatible', $url); - if (!isset($parsers['primary']) && is_string($type)) { - $success = TRUE; - $parsers['primary'] = $parser; - } - else if (is_string($type)) { - $parsers['secondary'][] = $parser; - } - } - } - } - } - if (!$success) { - // We can't find a suitable parser at all - return array('type' => '', 'parser' => '', 'processor_item' => ''); - } - // Get the feed item processor's weight - $all_processors = module_implements('feedapi_item'); - foreach ($all_processors as $processor) { - if (in_array($type, module_invoke($processor, 'feedapi_item', 'type'))) { - $processors[] = $processor; - } - } - $processors = array_intersect($processors, array_keys($node_type_settings['processors'])); - foreach ($processors as $processor) { - if ($node_type_settings['processors'][$processor]['enabled']) { - $sorted_processors[$node_type_settings['processors'][$processor]['weight']] = $processor; - } - } - return array( - 'type' => $type, - 'parsers' => $parsers, - 'processors' => $sorted_processors - ); -} - -/** * Add the element of the queue. This queue is fixed-length, the first element is discarded if full. + * Helper function for statistics handling */ function _feedapi_queue($queue, $new_elem) { if (empty($queue) || !isset($queue)) { @@ -1405,6 +1278,7 @@ $output .= "\n"; $output .= "\n"; drupal_set_header('Content-Type: text/xml; charset=utf-8'); + drupal_set_header('Content-Disposition: attachment; filename="'. variable_get('site_name', 'drupal') .'.opml"'); print $output; exit(0); } Index: feedapi_aggregator/feedapi_aggregator.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/feedapi/feedapi_aggregator/feedapi_aggregator.module,v retrieving revision 1.1.2.21 diff -u -r1.1.2.21 feedapi_aggregator.module --- feedapi_aggregator/feedapi_aggregator.module 30 Oct 2007 22:11:21 -0000 1.1.2.21 +++ feedapi_aggregator/feedapi_aggregator.module 13 Dec 2007 21:30:50 -0000 @@ -41,50 +41,62 @@ 'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -15, ); - $items[] = array('path' => 'admin/content/feed/category/add', + $items[] = array( + 'path' => 'admin/content/feed/category/add', 'title' => t('Add category'), 'callback' => 'drupal_get_form', 'callback arguments' => array('feedapi_aggregator_form_category'), 'access' => $edit, - 'type' => MENU_LOCAL_TASK); - - $items[] = array('path' => 'aggregator', + 'type' => MENU_LOCAL_TASK + ); + $items[] = array( + 'path' => 'aggregator', 'title' => t('News aggregator'), 'callback' => 'feedapi_aggregator_page_last', 'access' => $view, - 'weight' => 5); - $items[] = array('path' => 'aggregator/sources', + 'weight' => 5 + ); + $items[] = array( + 'path' => 'aggregator/sources', 'title' => t('Sources'), 'callback' => 'feedapi_aggregator_page_sources', - 'access' => $view); - $items[] = array('path' => 'aggregator/categories', + 'access' => $view + ); + $items[] = array( + 'path' => 'aggregator/categories', 'title' => t('Categories'), 'callback' => 'feedapi_aggregator_page_categories', 'access' => $view, - 'type' => MENU_ITEM_GROUPING); - $items[] = array('path' => 'aggregator/rss', + 'type' => MENU_ITEM_GROUPING + ); + $items[] = array( + 'path' => 'aggregator/rss', 'title' => t('RSS feed'), 'callback' => 'feedapi_aggregator_page_rss', 'access' => $view, - 'type' => MENU_CALLBACK); - $items[] = array('path' => 'aggregator/opml', + 'type' => MENU_CALLBACK + ); + $items[] = array( + 'path' => 'aggregator/opml', 'title' => t('OPML feed'), 'callback' => 'feedapi_aggregator_page_opml', 'access' => $view, - 'type' => MENU_CALLBACK); + 'type' => MENU_CALLBACK + ); $result = db_query('SELECT title, cid FROM {feedapi_aggregator_category} ORDER BY title'); while ($category = db_fetch_array($result)) { - $items[] = array('path' => 'aggregator/categories/'. $category['cid'], + $items[] = array( + 'path' => 'aggregator/categories/'. $category['cid'], 'title' => $category['title'], 'callback' => 'feedapi_aggregator_page_category', 'access' => $view); } - $items[] = array('path' => 'admin/settings/feedapi_aggregator', + $items[] = array( + 'path' => 'admin/settings/feedapi_aggregator', 'title' => t('FeedAPI Aggregator'), 'callback' => 'drupal_get_form', 'callback arguments' => array('feedapi_aggregator_admin_settings'), - 'type' => MENU_NORMAL_ITEM, 'access' => user_access('administer feedapi'), ); } @@ -185,8 +197,7 @@ '#default_value' => 3, '#options' => drupal_map_assoc(array(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)), ); - $categories_result = db_query('SELECT c.cid, c.title, ci.iid FROM {feedapi_aggregator_category} c LEFT JOIN {feedapi_aggregator_category_item} ci ON c.cid = ci.cid AND ci.iid = %d', $item->iid); - $selected = array(); + $categories_result = db_query('SELECT cid, title FROM {feedapi_aggregator_category}'); while ($category = db_fetch_object($categories_result)) { $categories[$category->cid] = check_plain($category->title); } Index: parser_common_syndication/parser_common_syndication.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/feedapi/parser_common_syndication/parser_common_syndication.module,v retrieving revision 1.6.2.10 diff -u -r1.6.2.10 parser_common_syndication.module --- parser_common_syndication/parser_common_syndication.module 27 Oct 2007 20:06:44 -0000 1.6.2.10 +++ parser_common_syndication/parser_common_syndication.module 13 Dec 2007 21:30:50 -0000 @@ -34,7 +34,7 @@ if (!function_exists('simplexml_load_string')) { return FALSE; } - $url = is_string($args[1]) ? $args[1] : FALSE; + $url = $args[1]->url; $downloaded_string = _parser_common_syndication_download($url, FALSE); if (!defined('LIBXML_VERSION') || (version_compare(phpversion(), '5.1.0', '<'))) { @ $xml = simplexml_load_string($downloaded_string, NULL); Index: parser_simplepie/parser_simplepie.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/feedapi/parser_simplepie/parser_simplepie.module,v retrieving revision 1.6.2.14 diff -u -r1.6.2.14 parser_simplepie.module --- parser_simplepie/parser_simplepie.module 13 Dec 2007 16:39:14 -0000 1.6.2.14 +++ parser_simplepie/parser_simplepie.module 13 Dec 2007 21:30:51 -0000 @@ -67,7 +67,7 @@ return array("XML feed"); break; case 'compatible': - $url = is_string($args[1]) ? $args[1] : FALSE; + $url = $args[1]->url; $parser = _parser_simplepie_get_parser($url); if ($parser->error) { return FALSE;