Index: feedapi.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feedapi/feedapi.module,v
retrieving revision 1.23.2.119.2.15
diff -u -r1.23.2.119.2.15 feedapi.module
--- feedapi.module	9 May 2008 13:30:34 -0000	1.23.2.119.2.15
+++ feedapi.module	12 May 2008 15:39:13 -0000
@@ -45,6 +45,7 @@
     'description' => 'Overview which content your site aggregates from other sites and see detailed statistics about the feeds.',
     'page callback' => 'feedapi_management_page',
     'access arguments' => array('administer feedapi'),
+    'file' => 'feedapi.admin.inc',
   );
   $items['admin/content/feed/list'] = array(
     'title' => 'List',
@@ -57,17 +58,20 @@
     'access arguments' => array('administer feedapi'),
     'page callback' => 'drupal_get_form',
     'page arguments' => array('feedapi_import_feeds_form'),
+    'file' => 'feedapi.admin.inc',
   );
   $items['admin/content/feed/export_opml'] = array(
     'title' => 'Export all feeds as OPML',
     'access arguments' => array('administer feedapi'),
     'page callback' => '_feedapi_export_opml',
+    'file' => 'feedapi.admin.inc',
   );
   $items['admin/settings/feedapi'] = array(
     'title' => 'FeedAPI settings',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('feedapi_admin_settings'),
     'access arguments' => array('administer feedapi'),
+    'file' => 'feedapi.admin.inc',
   );
   
   $items['node/%node/refresh'] = array(
@@ -268,62 +272,6 @@
 }
 
 /**
- * OPML Feed import form, also allows setting defaults to be applied to each feed
- */
-function feedapi_import_feeds_form() {
-  $form['opml'] = array(
-    '#type' => 'file',
-    '#title' => t('OPML File'),
-    '#size' => 50,
-    '#description' => t('Upload an OPML file containing a list of newsfeeds to be imported.'),
-  );
-  $form['feed_type'] = array(
-    '#type' => 'select',
-    '#title' => t('Feed Type'),
-    '#description' => t("The type of feed you would like to associate this import with."),
-    '#options' => _feedapi_content_types_list(),
-    '#required' => TRUE,
-  );
-  $form['override_title'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Use TITLE attribute of OPML entries as feed title'),
-    '#description' => t('If checked feed title will be overriden with the information from OPML file'),
-  );
-  $form['override_body'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Use TEXT attribute of OPML entries as feed description'),
-    '#description' => t('If checked feed description will be overriden with the information from OPML file'),
-  ); 
-  $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);
-  }
-  return $form;
-}
-
-/**
- * Handle the submission of the OPML import form
- */
-function feedapi_import_feeds_form_submit($form, &$form_state) {
-  $file = file_save_upload('opml');
-  if ($file = file($file->filepath)) {
-    $file = implode('', $file);
-
-    if ($count = _feedapi_import_opml_process($file, $form_state['values'])) {
-      drupal_set_message(t('Successfuly imported %count feeds from OPML', array('%count' => $count)));
-    }
-    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');
-  }
-  $form_state['redirect'] = 'admin/content/feed';
-}
-
-/**
  * Delete expired items and return informations about the feed refreshing
  * 
  * @param $feed
@@ -672,62 +620,6 @@
 }
 
 /**
- * Provide a UI for overviewing the existing feeds
- */
-function feedapi_management_page() {
-  $header = array(
-    t('Title'),
-    t('Last refresh'),
-    t('New items added per update'),
-    t('Update rate'),
-    t('Number of items'),
-    t('Processing time'),
-    t('Commands'),
-  );
-  $rows = array();
-  $result = pager_query("SELECT nid from {feedapi} ORDER BY checked DESC", 50, 0, "SELECT count(*) FROM {feedapi}");
-  while ($nid = db_fetch_array($result)) {
-    $nid = $nid['nid'];
-    $node = node_load($nid);
-    $commands = array(l(t('Delete'), 'node/'. $node->nid .'/delete', array('query' => 'destination=admin/content/feed')),
-      l(t('Remove items'), 'node/'. $node->nid .'/purge', array('query' => 'destination=admin/content/feed')),
-      l(t('Refresh'), 'node/'. $node->nid .'/refresh'),
-      l(t('Edit'), 'node/'. $node->nid .'/edit'),
-    );
-    // Fetch statistics for this feed
-    foreach (array('download_num', 'new',  'process_time', 'update_times') as $type) {
-      $node->feed->statistics[$type] = _feedapi_get_stat($node->nid, $type, TRUE);
-    }
-    if (count($node->feed->statistics['download_num']) != 0 && count($node->feed->statistics['new']) != 0 && count($node->feed->statistics['process_time']) != 0) {
-      $update_rate = _feedapi_update_rate($node->feed->statistics['update_times']);
-      $rows[] = array(
-        l($node->title, "node/$node->nid"),
-        $node->feed->checked == 0 ? t('Never') : t('%time ago', array('%time' => format_interval(time() - $node->feed->checked))), 
-        round(array_sum($node->feed->statistics['new']) / count($node->feed->statistics['new']), 2),
-        is_numeric($update_rate) ? format_interval($update_rate) : $update_rate,
-        round((array_sum($node->feed->statistics['download_num']) / count($node->feed->statistics['download_num'])), 2),
-        round((array_sum($node->feed->statistics['process_time']) / count($node->feed->statistics['process_time'])), 2) .' '. t('ms'),
-        theme('item_list', $commands),
-      );
-    }
-    else {
-      $rows[] = array(
-        l($node->title, "node/$node->nid"),
-        $node->feed->checked == 0 ? t('Never') : t('%time ago', array('%time' => format_interval(time() - $node->feed->checked))),
-        '', '', t('No enough data for statistics'), '',
-        theme('item_list', $commands),
-      );
-    }
-  }
-  $output = format_plural(round(FEEDAPI_CRON_STAT_LIFETIME / (24*3600)), "Average over the last day.",
-    "Averages over the last @count days."
-  );
-  $output .= theme('table', $header, $rows);
-  $output .= theme('pager', 0, 50);
-  return $output;
-}
-
-/**
  * This is shown instead of normal node form when the simplified form is chosen at the settings
  */
 function feedapi_simplified_form($form_state, $type) {
@@ -791,37 +683,6 @@
 }
 
 /**
- * Settings: allowed HTML tags, number of feeds refreshed in one round
- */
-function feedapi_admin_settings() {
-  $form['feedapi_allowed_html_tags'] = array(
-    '#type' => 'textfield', '#title' => t('Allowed HTML tags'), '#size' => 80, '#maxlength' => 255,
-    '#default_value' => variable_get('feedapi_allowed_html_tags', '<a> <b> <br> <dd> <dl> <dt> <em> <i> <li> <ol> <p> <strong> <u> <ul>'),
-    '#description' => t('The list of tags which are allowed in feeds, i.e., which will not be removed by Drupal.')
-  );
-  $form['feedapi_allow_html_all'] = array(
-    '#type' => 'checkbox', '#title' => t('Allow all HTML tags'),
-    '#default_value' => variable_get('feedapi_allow_html_all', FALSE),
-    '#description' => t('In this case the module does\'t filter any HTML elements from the incoming fields. This checkbox overrides the above list of allowed tags.')
-  );
-  if (variable_get('feedapi_allow_html_all', FALSE)) {
-    $form['feedapi_allowed_html_tags']['#disabled'] = TRUE;
-  }
-  // Drupal will try to overwrite this value at cron time
-  $max_exec = !ini_get('safe_mode') ? 240 : ini_get('max_execution_time');
-  $form['feedapi_cron_percentage'] = array(
-    '#type' => 'select', 
-    '#title' => t('Cron time for FeedAPI [%]'),
-    '#options' => drupal_map_assoc(array(15, 25, 50, 75)),
-    '#default_value' => variable_get('feedapi_cron_percentage', 15),
-    '#description' => t('Percentage of maximal PHP execution time (currently !exec seconds).
-                         At current settings, the FeedAPI cron process can run for up to !now seconds.',
-                         array("!exec" => $max_exec, "!now" => (variable_get('feedapi_cron_percentage', 15) / 100) * $max_exec)),
-  );
-  return system_settings_form($form);
-}
-
-/**
  * Create a feedapi node programatically.
  * 
  * @param $param
@@ -1405,71 +1266,6 @@
 }
 
 /**
- * Generates an OPML representation of all feeds.
- */
-function _feedapi_export_opml() {
-  $result = db_query(db_rewrite_sql('SELECT n.title, f.url FROM {feedapi} f INNER JOIN {node} n ON f.nid = n.nid ORDER BY n.title ASC'));
-  $output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
-  $output .= "<opml version=\"1.1\">\n";
-  $output .= "<head>\n";
-  $output .= '<title>'. variable_get('site_name', 'drupal') .' - '. variable_get('site_slogan', '') ."</title>\n";
-  $output .= '<dateModified>'. gmdate('r') ."</dateModified>\n";
-  $output .= "</head>\n";
-  $output .= "<body>\n";
-  while ($feed = db_fetch_object($result)) {
-    $output .= '<outline text="'. check_plain($feed->title) .'" xmlUrl="'. check_plain($feed->url) .'" />'."\n";
-  }
-  $output .= "</body>\n";
-  $output .= "</opml>\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;
-}
-
-/**
-* Imports from OPML XML file
-*/
-function _feedapi_import_opml_process($opml, $args = array()) {
-  $feeds = array();
-  $count = 0;
-  $parser = drupal_xml_parser_create($opml);
-
-  //Some OPML Files don't have the xml tag, which causes parsing to fail. Hence, using the appended version as a fallback parse
-  if (xml_parse_into_struct($parser, $opml, $vals, $index) || xml_parse_into_struct($parser, '<?xml version="1.0"?>'. $opml, $vals, $index)) {
-    foreach ($vals as $entry) {
-      if ($entry['tag'] == 'OUTLINE') {
-        $feeds[] = $entry['attributes'];
-      }
-    }
-    
-    foreach ($feeds as $feed) {
-      if (strlen($feed['XMLURL']) > 1) {
-        // check if feed url is already in the list
-        $dupe = db_result(db_query("SELECT nid FROM {feedapi} WHERE url = '%s'", $feed['XMLURL']));
-
-        // If the feed is not already in the list, add it
-        if ($dupe === FALSE) {
-          // Generate a feed structure
-          $node = new stdClass();
-          $node->type = $args['feed_type'];
-          if ($args['override_title']) {
-            $node->title = $feed['TITLE'];
-          }
-          if ($args['override_body']) {
-            $node->body = $feed['TEXT'];
-          }
-          $node->og_groups = $args['og_groups'];
-          $node->og_public = (int) $args['og_public'];
-          $node = feedapi_create_node($node, $feed['XMLURL']);
-          $count++;
-        }
-      }
-    }
-  }
-  return $count;
-}
-
-/**
  * Store statistics information
  *
  * @param $id
Index: feedapi.admin.inc
===================================================================
RCS file: feedapi.admin.inc
diff -N feedapi.admin.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ feedapi.admin.inc	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,225 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Admin page callbacks for the FeedAPI module.
+ */
+
+/**
+ * Menu callback; provide a UI for overviewing existing feeds.
+ */
+function feedapi_management_page() {
+  $header = array(
+    t('Title'),
+    t('Last refresh'),
+    t('New items added per update'),
+    t('Update rate'),
+    t('Number of items'),
+    t('Processing time'),
+    t('Commands'),
+  );
+  $rows = array();
+  $result = pager_query("SELECT nid from {feedapi} ORDER BY checked DESC", 50, 0, "SELECT count(*) FROM {feedapi}");
+  while ($nid = db_fetch_array($result)) {
+    $nid = $nid['nid'];
+    $node = node_load($nid);
+    $commands = array(l(t('Delete'), 'node/'. $node->nid .'/delete', array('query' => 'destination=admin/content/feed')),
+      l(t('Remove items'), 'node/'. $node->nid .'/purge', array('query' => 'destination=admin/content/feed')),
+      l(t('Refresh'), 'node/'. $node->nid .'/refresh'),
+      l(t('Edit'), 'node/'. $node->nid .'/edit'),
+    );
+    // Fetch statistics for this feed.
+    foreach (array('download_num', 'new',  'process_time', 'update_times') as $type) {
+      $node->feed->statistics[$type] = _feedapi_get_stat($node->nid, $type, TRUE);
+    }
+    if (count($node->feed->statistics['download_num']) != 0 && count($node->feed->statistics['new']) != 0 && count($node->feed->statistics['process_time']) != 0) {
+      $update_rate = _feedapi_update_rate($node->feed->statistics['update_times']);
+      $rows[] = array(
+        l($node->title, "node/$node->nid"),
+        $node->feed->checked == 0 ? t('Never') : t('%time ago', array('%time' => format_interval(time() - $node->feed->checked))), 
+        round(array_sum($node->feed->statistics['new']) / count($node->feed->statistics['new']), 2),
+        is_numeric($update_rate) ? format_interval($update_rate) : $update_rate,
+        round((array_sum($node->feed->statistics['download_num']) / count($node->feed->statistics['download_num'])), 2),
+        round((array_sum($node->feed->statistics['process_time']) / count($node->feed->statistics['process_time'])), 2) .' '. t('ms'),
+        theme('item_list', $commands),
+      );
+    }
+    else {
+      $rows[] = array(
+        l($node->title, "node/$node->nid"),
+        $node->feed->checked == 0 ? t('Never') : t('%time ago', array('%time' => format_interval(time() - $node->feed->checked))),
+        '', '', t('No enough data for statistics'), '',
+        theme('item_list', $commands),
+      );
+    }
+  }
+  $output = format_plural(round(FEEDAPI_CRON_STAT_LIFETIME / (24*3600)), "Average over the last day.",
+    "Averages over the last @count days."
+  );
+  $output .= theme('table', $header, $rows);
+  $output .= theme('pager', 0, 50);
+  return $output;
+}
+
+/**
+ * Form builder; OPML import form, also allows default settings to be applied to each feed.
+ *
+ * @ingroup forms
+ * @see feedapi_import_feeds_form_submit()
+ */
+function feedapi_import_feeds_form() {
+  $form['opml'] = array(
+    '#type' => 'file',
+    '#title' => t('OPML File'),
+    '#size' => 50,
+    '#description' => t('Upload an OPML file containing a list of newsfeeds to be imported.'),
+  );
+  $form['feed_type'] = array(
+    '#type' => 'select',
+    '#title' => t('Feed Type'),
+    '#description' => t("The type of feed you would like to associate this import with."),
+    '#options' => _feedapi_content_types_list(),
+    '#required' => TRUE,
+  );
+  $form['override_title'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Use TITLE attribute of OPML entries as feed title'),
+    '#description' => t('If checked feed title will be overriden with the information from OPML file'),
+  );
+  $form['override_body'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Use TEXT attribute of OPML entries as feed description'),
+    '#description' => t('If checked feed description will be overriden with the information from OPML file'),
+  ); 
+  $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);
+  }
+  return $form;
+}
+
+/**
+ * Process feedapi_import_feeds_form form submissions.
+ */
+function feedapi_import_feeds_form_submit($form, &$form_state) {
+  $file = file_save_upload('opml');
+  if ($file = file($file->filepath)) {
+    $file = implode('', $file);
+
+    if ($count = _feedapi_import_opml($file, $form_state['values'])) {
+      drupal_set_message(t('Successfuly imported %count feeds from OPML', array('%count' => $count)));
+    }
+    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');
+  }
+  $form_state['redirect'] = 'admin/content/feed';
+}
+
+/**
+ * Helper function for feedapi_import_feeds_form_submit.
+ * 
+ * Import feeds from OPML XML file.
+ */
+function _feedapi_import_opml($opml, $args = array()) {
+  $count = 0;
+  $parser = drupal_xml_parser_create($opml);
+
+  // Some OPML Files don't have the xml tag, which causes parsing to fail.
+  // Hence, using the appended version as a fallback parse.
+  if (xml_parse_into_struct($parser, $opml, $vals, $index) || xml_parse_into_struct($parser, '<?xml version="1.0"?>'. $opml, $vals, $index)) {
+    $feeds = array();
+    foreach ($vals as $entry) {
+      if ($entry['tag'] == 'OUTLINE') {
+        $feeds[] = $entry['attributes'];
+      }
+    }
+    
+    foreach ($feeds as $feed) {
+      if (strlen($feed['XMLURL']) > 1) {
+        // Check if feed url is already in the list.
+        $dupe = db_result(db_query("SELECT nid FROM {feedapi} WHERE url = '%s'", $feed['XMLURL']));
+
+        // If the feed is not already in the list, add it.
+        if ($dupe === FALSE) {
+          // Generate a feed structure.
+          $node = new stdClass();
+          $node->type = $args['feed_type'];
+          if ($args['override_title']) {
+            $node->title = $feed['TITLE'];
+          }
+          if ($args['override_body']) {
+            $node->body = $feed['TEXT'];
+          }
+          $node->og_groups = $args['og_groups'];
+          $node->og_public = (int) $args['og_public'];
+          $node = feedapi_create_node($node, $feed['XMLURL']);
+          $count++;
+        }
+      }
+    }
+  }
+  return $count;
+}
+
+/**
+ * Form builder; Configure the FeedAPI system.
+ * 
+ * Settings: Allowed HTML tags, number of feeds refreshed in one round.
+ *
+ * @ingroup forms
+ * @see system_settings_form()
+ */
+function feedapi_admin_settings() {
+  $form['feedapi_allowed_html_tags'] = array(
+    '#type' => 'textfield', '#title' => t('Allowed HTML tags'), '#size' => 80, '#maxlength' => 255,
+    '#default_value' => variable_get('feedapi_allowed_html_tags', '<a> <b> <br> <dd> <dl> <dt> <em> <i> <li> <ol> <p> <strong> <u> <ul>'),
+    '#description' => t('The list of tags which are allowed in feeds, i.e., which will not be removed by Drupal.')
+  );
+  $form['feedapi_allow_html_all'] = array(
+    '#type' => 'checkbox', '#title' => t('Allow all HTML tags'),
+    '#default_value' => variable_get('feedapi_allow_html_all', FALSE),
+    '#description' => t('In this case the module does\'t filter any HTML elements from the incoming fields. This checkbox overrides the above list of allowed tags.')
+  );
+  if (variable_get('feedapi_allow_html_all', FALSE)) {
+    $form['feedapi_allowed_html_tags']['#disabled'] = TRUE;
+  }
+  // Drupal will try to overwrite this value at cron time.
+  $max_exec = !ini_get('safe_mode') ? 240 : ini_get('max_execution_time');
+  $form['feedapi_cron_percentage'] = array(
+    '#type' => 'select', 
+    '#title' => t('Cron time for FeedAPI [%]'),
+    '#options' => drupal_map_assoc(array(15, 25, 50, 75)),
+    '#default_value' => variable_get('feedapi_cron_percentage', 15),
+    '#description' => t('Percentage of maximal PHP execution time (currently !exec seconds). At current settings, the FeedAPI cron process can run for up to !now seconds.',
+      array("!exec" => $max_exec, "!now" => (variable_get('feedapi_cron_percentage', 15) / 100) * $max_exec)),
+  );
+  return system_settings_form($form);
+}
+
+/**
+ * Menu callback; generate an OPML representation of all feeds.
+ */
+function _feedapi_export_opml() {
+  $result = db_query(db_rewrite_sql('SELECT n.title, f.url FROM {feedapi} f INNER JOIN {node} n ON f.nid = n.nid ORDER BY n.title ASC'));
+  $output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
+  $output .= "<opml version=\"1.1\">\n";
+  $output .= "<head>\n";
+  $output .= '<title>'. variable_get('site_name', 'drupal') .' - '. variable_get('site_slogan', '') ."</title>\n";
+  $output .= '<dateModified>'. gmdate('r') ."</dateModified>\n";
+  $output .= "</head>\n";
+  $output .= "<body>\n";
+  while ($feed = db_fetch_object($result)) {
+    $output .= '<outline text="'. check_plain($feed->title) .'" xmlUrl="'. check_plain($feed->url) .'" />'."\n";
+  }
+  $output .= "</body>\n";
+  $output .= "</opml>\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;
+}
