? filename.patch
? patch.patch
Index: views_node_feed.admin.inc
===================================================================
RCS file: views_node_feed.admin.inc
diff -N views_node_feed.admin.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ views_node_feed.admin.inc	15 Apr 2009 16:50:06 -0000
@@ -0,0 +1,248 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Administration functions
+ */
+
+
+function views_node_feed_list_feeds_page() {
+  $feeds = views_node_feed_get_feeds(TRUE);
+  return theme('views_node_feed_list_feeds', $feeds);
+}
+
+/**
+ * version update helper
+ */
+function views_node_feed_set_used_by($view, $feedid) {
+  $view['display_options']['style_options']['format'] = $feedid;
+  $sql = "UPDATE {views_display} SET display_options = '%s' WHERE vid = %d AND id = '%s'";
+  db_query($sql, serialize($view['display_options']), $view['vid'], $view['id']);
+}
+
+function views_node_feed_feed_view($feed) {
+  drupal_add_css(drupal_get_path('module', 'views_node_feed') .'/views_node_feed.css');
+  return theme('views_node_feed_feed_view', $feed);
+}
+
+/**
+ *  Provide the Views Node Feed create/edit form
+ */
+function views_node_feed_feed_edit_form($form_state, $feed = NULL) {
+  if ($feed === NULL) {
+    $feed = array(
+      'feedid'      => 0,
+      'title'       => '',
+      'description' => '',
+      'wrapper'     => "<?php\n".
+                       "  //short open tag safe\n".
+                       "  echo \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n\";\n".
+                       "?>\n".
+                       "<nodes>\n".
+                       "***VIEWS_NODE_FEED_ITEMS***\n".
+                       "</nodes>\n",
+
+      'node'        => "<?php\n".
+                       "  echo '  <node>'. \$node->title .'</node>';\n".
+                       "?>\n",
+    );
+  }
+
+  $form = array();
+  $form['feedid'] = array(
+    '#type'  => 'value',
+    '#value' => $feed['feedid'],
+  );
+  $form['title'] = array(
+    '#type'          => 'textfield',
+    '#title'         => t('Feed identifier'),
+    '#description'   => t('Name with which you will identify this node feed. Only letters, numbers and underscores allowed.'),
+    '#maxlength'     => 255,
+    '#required'      => TRUE,
+    '#default_value' => $feed['title'],
+  );
+
+  $form['description'] = array(
+    '#type'          => 'textarea',
+    '#title'         => t('Description'),
+    '#default_value' => $feed['description'],
+    '#required'      => FALSE,
+  );
+
+  $form['wrapper'] = array(
+    '#type'          => 'textarea',
+    '#title'         => t('Wrapper Feed'),
+    '#description'   => t('Feed that will be placed around the list of nodes. Be sure to include the string ***VIEWS_NODE_FEED_ITEMS*** which will automatically be replaced with the necessary items. The variables $view, $nodes, and $type will be available.'),
+    '#default_value' => $feed['wrapper'],
+    '#rows'          => 8,
+    '#required'      => FALSE,
+  );
+
+  $form['node'] = array(
+    '#type'          => 'textarea',
+    '#title'         => t('Node feed'),
+    '#description'   => t('Feed that will be generated for each node. The variables $view, $nodes, $node, and $type will be available.'),
+    '#default_value' => $feed['node'],
+    '#rows'          => 8,
+    '#required'      => FALSE,
+  );
+
+  $form['submit'] = array(
+    '#type'  => 'submit',
+    '#value' => $feed['feedid'] ? t('Edit') : t('Save'),
+  );
+
+  if ($feed['feedid']) {
+    $form['submit']['#suffix'] = l('Delete', "admin/settings/views_node_feed/{$feed['feedid']}/delete");
+  }
+
+  drupal_add_css(drupal_get_path('module', 'views_node_feed') .'/views_node_feed.css');
+  return $form;
+}
+
+/**
+ *  Validate the Views Node Feed create/edit form
+ */
+function views_node_feed_feed_edit_form_validate($form, &$form_state) {
+  $form_state['values']['title'] = trim($form_state['values']['title']);
+  if (!strlen($form_state['values']['title'])) {
+    form_set_error('title', t('Invalid feed title'));
+    return;
+  }
+
+  $sql = "SELECT feedid, title FROM {views_node_feed_feeds} WHERE title = '%s' AND feedid <> %d";
+  $dbr = db_query($sql, $form_state['values']['title'], $form_state['values']['feedid']);
+  if ($row = db_fetch_object($dbr)) {
+    form_set_error('title',
+      t('Feed identifier already exists.')
+      .' '.
+      l($row->title, "admin/settings/views_node_feed/{$row->feedid}")
+    );
+  }
+}
+
+/**
+ *  Process submission of the Views Node Feed create/edit form
+ */
+function views_node_feed_feed_edit_form_submit($form, &$form_state) {
+  $feed = (($form_state['values']['feedid']) ?
+    views_node_feed_feed_update($form_state['values'])
+    :
+    views_node_feed_feed_add($form_state['values'])
+  );
+  if (!$feed) {
+    //@TODO error message
+  }
+  else {
+    $form_state['redirect'] = 'admin/settings/views_node_feed/'. $feed['feedid'];
+  }
+}
+
+
+
+/**
+ *  Provide the Views Node Feed delete form
+ */
+function views_node_feed_feed_delete_form($form_state, $feed) {
+  $form['feed'] = array(
+    '#type'  => 'value',
+    '#value' => $feed,
+  );
+  $form['#redirect'] = 'admin/settings/views_node_feed';
+
+  return confirm_form(
+    $form,
+    t('Delete the node feed %feed?', array('%feed' => $feed['title'])),
+    'admin/settings/views_node_feed',
+    t('This will delete the node feed %feed.', array('%feed' => $feed['title'])),
+    t('Delete'),
+    t('Cancel')
+  );
+}
+
+function views_node_feed_feed_delete_form_validate($form, &$form_state) {
+  if (count($form_state['values']['feed']['used_by'])) {
+    $used_by = $form_state['values']['feed']['used_by'];
+    $items = array();
+    foreach ($used_by as $vid => $view) {
+      $items[] = l("{$view['name']}/{$view['display_title']}", "admin/build/views/edit/{$view['name']}");
+    }
+    form_set_error('', t('This feed already in use') . theme('item_list', $items));
+  }
+}
+
+/**
+ *  Process submission of the Views Node Feed delete form
+ */
+function views_node_feed_feed_delete_form_submit($form, &$form_state) {
+  views_node_feed_feed_delete($form_state['values']['feed']);
+}
+
+
+
+/**
+ * @ingroup themeable
+ */
+function theme_views_node_feed_feed_view($feed) {
+  $output = '<div id="views-node-feed-feed-view">';
+
+  $used_by = array();
+  foreach ($feed['used_by'] as $vid => $view) {
+    $used_by[] = l("{$view['name']}/{$view['display_title']}", "admin/build/views/edit/{$view['name']}");
+  }
+
+  $used_by = ((!count($used_by)) ? t('[Not used]') : theme('item_list', $used_by));
+
+  $pattern = '<label>%s:</label><div id="views-node-feed-feed-view-%s">%s</div>';
+  $output .= sprintf($pattern, t('Title'),       'title',       check_plain($feed['title']));
+  $output .= sprintf($pattern, t('Description'), 'description', check_plain($feed['description']));
+  $output .= sprintf($pattern, t('Wrapper'),     'wrapper',     highlight_string($feed['wrapper'], TRUE));
+  $output .= sprintf($pattern, t('Node'),        'node',        highlight_string($feed['node'], TRUE));
+  $output .= sprintf($pattern, t('Used by'),     'used-by',     $used_by);
+
+  $output .= '</div>';
+  return $output;
+}
+
+/**
+ * themes the views_node_feed feeds list
+ *
+ * @ingroup themeable
+ */
+function theme_views_node_feed_list_feeds($feeds) {
+  if (!count($feeds)) {
+    return t('No existing node feeds');
+  }
+
+  $header = array(
+    array('data' => t('Title')),
+    array('data' => t('Description')),
+    array('data' => t('Used by')),
+    array('data' => t('Operations')),
+  );
+
+  $rows = array();
+  foreach ($feeds as $feed) {
+    $path = "admin/settings/views_node_feed/{$feed['feedid']}";
+    $used_by = array();
+    foreach ($feed['used_by'] as $vid => $view) {
+      $used_by[] = l("{$view['name']}/{$view['display_title']}", "admin/build/views/edit/{$view['name']}");
+    }
+
+    $used = (count($used_by));
+
+    $row = array();
+    $row[0] = l($feed['title'], $path);
+    $row[1] = $feed['description'];
+    $row[2] = (($used) ? theme('item_list', $used_by) : t('[Not used]'));
+    $row[3][] = l('Edit', "$path/edit");
+
+    if (!$used) {
+      $row[3][] = l('Delete', "$path/delete");
+    }
+    $row[3] = implode(' | ', $row[3]);
+    $rows[] = $row;
+  }
+  return theme('table', $header, $rows);
+}
Index: views_node_feed.css
===================================================================
RCS file: views_node_feed.css
diff -N views_node_feed.css
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ views_node_feed.css	15 Apr 2009 16:50:06 -0000
@@ -0,0 +1,22 @@
+#views-node-feed-feed-edit-form #edit-wrapper,
+#views-node-feed-feed-edit-form #edit-node,
+#views-node-feed-feed-view-wrapper,
+#views-node-feed-feed-view-node
+{
+  font-family: "DejaVu Sans Mono", "Courier New", monospace;
+  font-size: 14px;
+}
+
+#views-node-feed-feed-view-wrapper,
+#views-node-feed-feed-view-node
+{
+  /*white-space:pre;*/
+  overflow   :auto;
+  max-height :650px;
+  border: 1px solid black;
+  margin: 0px 0px 15px 0px;
+}
+
+#views-node-feed-feed-view label {
+  font-weight: bolder;
+}
Index: views_node_feed.install
===================================================================
RCS file: views_node_feed.install
diff -N views_node_feed.install
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ views_node_feed.install	15 Apr 2009 16:50:06 -0000
@@ -0,0 +1,106 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Install and uninstall functions
+ */
+
+/**
+ * Implementation of hook_schema().
+ */
+function views_node_feed_schema() {
+  $schema['views_node_feed_feeds'] = array(
+    'fields' => array(
+      'feedid' => array(
+        'type'        => 'serial',
+        'unsigned'    => TRUE,
+        'not null'    => TRUE,
+        'description' => '',
+      ),
+
+      'title' => array(
+        'type'        => 'varchar',
+        'length'      => 255,
+        'not null'    => TRUE,
+        'default'     => '',
+        'description' => '',
+      ),
+
+      'description' => array(
+        'type'        => 'text',
+        'not null'    => TRUE,
+        'size'        => 'big',
+        'description' => '',
+      ),
+
+      'wrapper' => array(
+        'type'        => 'text',
+        'not null'    => TRUE,
+        'size'        => 'big',
+        'description' => '',
+      ),
+
+      'node' => array(
+        'type'        => 'text',
+        'not null'    => TRUE,
+        'size'        => 'big',
+        'description' => '',
+      ),
+    ),
+
+    'primary key' => array('feedid'),
+
+    'indexes' => array(
+      'title' => array('title'),
+    ),
+  );
+
+  return $schema;
+}
+
+/**
+ * Implementation of hook_install().
+ */
+function views_node_feed_install() {
+  // Create tables.
+  drupal_install_schema('views_node_feed');
+}
+
+/**
+ * Implementation of hook_uninstall().
+ */
+function views_node_feed_uninstall() {
+  // Remove tables.
+  drupal_uninstall_schema('views_node_feed');
+}
+
+/**
+ * Implementation of hook_update_N().
+ */
+function views_node_feed_update_6000() {
+  module_load_include('inc', 'views_node_feed', 'views_node_feed.admin');
+
+  drupal_install_schema('views_node_feed');
+
+  $feeds = variable_get('views_node_feed_feeds', array());
+  foreach ($feeds as $ident) {
+    $feed_old = variable_get("views_node_feed_{$ident}", array('wrapper' => '', 'node' => ''));
+    $feed_new = array(
+      'title'       => $ident,
+      'description' => '',
+      'wrapper'     => $feed_old['wrapper'],
+      'node'        => $feed_old['node'],
+    );
+
+    if ($feed_new = views_node_feed_feed_add($feed_new)) {
+      foreach (views_node_feed_get_used_by($ident) as $view) {
+        views_node_feed_set_used_by($view, $feed_new['feedid']);
+      }
+    }
+    variable_del("views_node_feed_{$ident}");
+  }
+  variable_del('views_node_feed_feeds');
+
+  return array();
+}
Index: views_node_feed.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views_node_feed/views_node_feed.module,v
retrieving revision 1.1.2.1.2.1
diff -u -p -r1.1.2.1.2.1 views_node_feed.module
--- views_node_feed.module	7 Dec 2008 05:33:02 -0000	1.1.2.1.2.1
+++ views_node_feed.module	15 Apr 2009 16:50:07 -0000
@@ -21,21 +21,40 @@ function views_node_feed_views_api() {
  */
 function views_node_feed_theme($existing, $type, $theme, $path) {
   return array(
-    'views_node_feed_admin' => array(
+    'views_node_feed' => array(
+      'arguments' => array(
+        'view'  => NULL,
+        'nodes' => NULL,
+        'type'  => NULL
+      ),
+    ),
+
+    'views_node_feed_list_feeds' => array(
       'arguments' => array(
         'feeds' => NULL,
       ),
+      'file' => 'views_node_feed.admin.inc',
     ),
-    'views_node_feed' => array(
+
+    'views_node_feed_feed_view' => array(
       'arguments' => array(
-        'view' => NULL,
-        'nodes' => NULL,
-        'type' => NULL
+        'feed' => NULL
       ),
+      'file' => 'views_node_feed.admin.inc',
     ),
   );
 }
 
+/**
+ * Implementation of hook_perm().
+ */
+function views_node_feed_perm() {
+  return array(
+    'Create views node feed',
+    'Edit views node feed',
+    'Delete views node feed',
+  );
+}
 
 /**
  * Implementation of hook_menu().
@@ -43,210 +62,184 @@ function views_node_feed_theme($existing
 function views_node_feed_menu() {
   $items = array();
   $items['admin/settings/views_node_feed'] = array(
-    'title' => 'Views Node Feed',
-    'description' => 'Manage Different Types of Node Feeds',
+    'title'            => 'Views Node Feed',
+    'description'      => 'Manage Different Types of Node Feeds',
     'access arguments' => array('administer views'),
-    'page callback' => 'views_node_feed_admin_settings',
-    'type' => MENU_NORMAL_ITEM,
-  );
-  $items['admin/settings/views_node_feed/edit'] = array(
-    'title' => 'Add/Edit Node Feed',
-    'title callback' => '_views_node_feed_edit_title_callback',
-    'title arguments' => array(4, "test"),
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('views_node_feed_edit_form'),
+    'page callback'    => 'views_node_feed_list_feeds_page',
+    'type'             => MENU_NORMAL_ITEM,
+    'file'             => 'views_node_feed.admin.inc',
+  );
+
+  $items['admin/settings/views_node_feed/list'] = array(
+    'title'  => 'List',
+    'type'   => MENU_DEFAULT_LOCAL_TASK,
+    'weight' => -10,
+    'file'   => 'views_node_feed.admin.inc',
+  );
+
+  $items['admin/settings/views_node_feed/add'] = array(
+    'title'            => 'Add',
+    'page callback'    => 'drupal_get_form',
+    'page arguments'   => array('views_node_feed_feed_edit_form'),
+    'access arguments' => array('Create views node feed'),
+    'type'             => MENU_LOCAL_TASK,
+    'file'             => 'views_node_feed.admin.inc',
+  );
+
+  $items['admin/settings/views_node_feed/%views_node_feed_feed'] = array(
+    'load arguments'   => array(TRUE),
+    'title callback'   => 'views_node_feed_page_title',
+    'title arguments'  => array(3),
+    'page callback'    => 'views_node_feed_feed_view',
+    'page arguments'   => array(3),
     'access arguments' => array('administer views'),
-    'type' => MENU_NORMAL_ITEM,
+    'type'             => MENU_CALLBACK,
+    'file'             => 'views_node_feed.admin.inc',
   );
-  $items['admin/settings/views_node_feed/delete'] = array(
-    'title' => 'Delete Node Feed',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('views_node_feed_delete_form'),
-    'access arguments' => array('Delete Node Feed'),
-    'type' => MENU_CALLBACK,
+
+  $items['admin/settings/views_node_feed/%views_node_feed_feed/view'] = array(
+    'title'  => 'View',
+    'type'   => MENU_DEFAULT_LOCAL_TASK,
+    'weight' => -10,
+    'file'   => 'views_node_feed.admin.inc',
+  );
+
+  $items['admin/settings/views_node_feed/%views_node_feed_feed/edit'] = array(
+    'load arguments'   => array(TRUE),
+    'title'            => 'Edit',
+    'page callback'    => 'drupal_get_form',
+    'page arguments'   => array('views_node_feed_feed_edit_form', 3),
+    'access arguments' => array('Edit views node feed'),
+    'type'             => MENU_LOCAL_TASK,
+    'file'             => 'views_node_feed.admin.inc',
+  );
+
+  $items['admin/settings/views_node_feed/%views_node_feed_feed/delete'] = array(
+    'load arguments'   => array(TRUE),
+    'title'            => 'Delete',
+    'page callback'    => 'drupal_get_form',
+    'page arguments'   => array('views_node_feed_feed_delete_form', 3),
+    'access arguments' => array('Delete views node feed'),
+    'type'             => MENU_CALLBACK,
+    'file'             => 'views_node_feed.admin.inc',
   );
   return $items;
 }
 
 /**
- *  Title Callback
- */
-function _views_node_feed_edit_title_callback() {
-  $op = (arg(4) == 'new') ? "New" : "Edit";
-  return t('!op Node Feed', array('!op' => $op));
-}
-
-/**
- *  Build the themed admin page
- */
-function views_node_feed_admin_settings() {
-  $feeds = views_node_feed_get_feeds();
-  return theme('views_node_feed_admin', $feeds);
-}
-
-/**
- *  Provide the Views Node Feed create/edit form
+ * Menu - argument load callback
  */
-function views_node_feed_edit_form($arg1, $ident) {
-  $new = $ident === 'new';
-  if (!$new) {
-    if (_views_node_feed_valid_identifier($ident)) {
-      $feed = views_node_feed_get_feeds($ident);
-    }
-    if (!$feed) {
-      drupal_not_found();
-      exit;
+function views_node_feed_feed_load($feedid, $full = FALSE) {
+  $sql = "SELECT * FROM {views_node_feed_feeds} WHERE feedid = %d";
+  $dbr = db_query($sql, $feedid);
+  if ($row = db_fetch_array($dbr)) {
+    if ($full) {
+      $row['used_by'] = views_node_feed_get_used_by($row['feedid']);
     }
+    return $row;
   }
-  $form = array();
-  $form['new'] = array(
-    '#type' => 'value',
-    '#value' => $new,
-  );
-  $form['identifier'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Feed identifier'),
-    '#description' => t('Name with which you will identify this node feed. Only letters, numbers and underscores allowed.'),
-    '#maxlength' => 50,
-    '#required' => TRUE,
-    '#default_value' => $new ? '' : $ident,
-  );
-  $form['wrapper'] = array(
-    '#type' => 'textarea',
-    '#title' => t('Wrapper Template'),
-    '#description' => t('Template that will be placed around the list of nodes. Be sure to include the string ***VIEWS_NODE_FEED_ITEMS*** which will automatically be replaced with the necessary items. The variables $view, $nodes, and $type will be available.'),
-    '#default_value' => $new ? '***VIEWS_NODE_FEED_ITEMS***' : $feed['wrapper'],
-    '#required' => FALSE,
-  );
-  $form['node'] = array(
-    '#type' => 'textarea',
-    '#title' => t('Node template'),
-    '#description' => t('Template that will be generated for each node. The variables $view, $nodes, $node, and $type will be available.'),
-    '#default_value' => $new ? '<?php print $node->title; ?><br/>' : $feed['node'],
-    '#required' => FALSE,
-  );
-  $form['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Save'),
-  );
-  return $form;
+
+  return FALSE;
 }
 
 /**
- *  Validate the Views Node Feed create/edit form
+ * Menu - page title callback
  */
-function views_node_feed_edit_form_validate($form, &$form_state) {
-  if (!_views_node_feed_valid_identifier($form_state['values']['identifier'])) {
-    form_set_error('identifier', t('Invalid feed identifier'));
-  }
-  $feeds = views_node_feed_get_feeds();
-  if ($form_state['values']['new'] && in_array($form_state['values']['identifier'], $feeds)) {
-    form_set_error('identifier', t('Feed identifier already exists.'));
-  }
+function views_node_feed_page_title($feed) {
+  return $feed['title'];
 }
 
-/**
- *  Process submission of the Views Node Feed create/edit form
- */
-function views_node_feed_edit_form_submit($form, &$form_state) {
-  $val = array(
-    'identifier' => $form_state['values']['identifier'],
-    'wrapper' => $form_state['values']['wrapper'],
-    'node' => $form_state['values']['node']
-  );
-  $ident = $form_state['values']['identifier'];
-  $feeds = views_node_feed_get_feeds();
-  $feeds[$ident] = $ident;
-  variable_set("views_node_feed_$ident", $val);
-  variable_set("views_node_feed_feeds", $feeds);
+function views_node_feed_feed_add($feed) {
+  $object = new stdClass();
+  $object->title       = $feed['title'];
+  $object->description = $feed['description'];
+  $object->wrapper     = $feed['wrapper'];
+  $object->node        = $feed['node'];
 
-  drupal_set_message(t('Node feed %feed updated', array('%feed' => $ident)));
-  $form_state['redirect'] = 'admin/settings/views_node_feed';
-}
+  $result = drupal_write_record('views_node_feed_feeds', $object);
+  if ($result == SAVED_NEW) {
+    drupal_set_message(t('Node feed !feed saved', array('!feed' => l($object->title, "admin/settings/views_node_feed/{$object->feedid}"))));
+    return (array)$object;
+  }
 
-/**
- *  Provide the Views Node Feed delete form
- */
-function views_node_feed_delete_form($info, $ident) {
-  $feeds = views_node_feed_get_feeds();
-  if (!in_array($ident, $feeds)) {
-    drupal_not_found();
-    exit;
-  }
-  $form['identifier'] = array('#type' => 'value', '#value' => $ident);
-  $form['#redirect'] = 'admin/settings/views_node_feed';
-  return confirm_form($form,
-    t('Delete the node feed %feed?', array('%feed' => $ident)),
-    'admin/settings/views_node_feed',
-    t('This will delete the node feed %feed.', array('%feed' => $ident)),
-    t('Delete'), t('Cancel'));
+  //@TODO error message
+  return FALSE;
 }
 
-/**
- *  Process submission of the Views Node Feed delete form
- */
-function views_node_feed_delete_form_submit($form, &$form_state) {
-  $feeds = views_node_feed_get_feeds();
-  $ident = $form_state['values']['identifier'];
-  unset($feeds[$ident]);
-  variable_del("views_node_feed_$ident");
-  variable_set("views_node_feed_feeds", $feeds);
-  drupal_set_message(t('Node feed %feed deleted.', array('%feed' => $ident)));
-}
+function views_node_feed_feed_update($feed) {
+  $sql = "
+    UPDATE
+      {views_node_feed_feeds}
+    SET
+      title       = '%s',
+      description = '%s',
+      wrapper     = '%s',
+      node        = '%s'
+    WHERE
+      feedid = %d
+  ";
 
-/**
- *  Ensure that the Views Node Feed identifier is valid
- */
-function _views_node_feed_valid_identifier($ident) {
-  $ident = (string)$ident;
-  if (drupal_strlen($ident) <=0 || drupal_strlen($ident) > 50) {
-    return FALSE;
-  }
-  $new = preg_replace('/[^a-zA-Z0-9_]/', '', $ident);
-  if ($new !== $ident) {
-    return FALSE;
+  if (db_query($sql, $feed['title'], $feed['description'], $feed['wrapper'], $feed['node'], $feed['feedid'])) {
+    drupal_set_message(t('Node feed !feed updated', array('!feed' => l($feed['title'], "admin/settings/views_node_feed/{$feed['feedid']}"))));
+    return $feed;
   }
-  return TRUE;
+
+  //@TODO error message
+  return FALSE;
 }
 
-/**
- * Get views_node_feed feeds
- * @param $ident
- * a string containing the views_node_feed feed identity
- * @return
- * An array of feeds
- */
-function views_node_feed_get_feeds($ident = NULL) {
-  if ($ident === NULL) {
-    return variable_get("views_node_feed_feeds", array());
+function views_node_feed_feed_delete($feed) {
+  $sql = "DELETE FROM {views_node_feed_feeds} WHERE feedid = %d";
+  $dbr = db_query($sql, $feed['feedid']);
+  if (db_affected_rows()) {
+    drupal_set_message(t('Node feed %feed deleted.', array('%feed' => $feed['title'])));
   }
-  else {
-    return variable_get("views_node_feed_$ident", FALSE);
+}
+
+function views_node_feed_get_feeds($full = FALSE) {
+  $feeds = array();
+  $sql = "SELECT * FROM {views_node_feed_feeds} ORDER BY title";
+  $dbr = db_query($sql);
+  while ($row = db_fetch_array($dbr)) {
+    if ($full) {
+      $row['used_by'] = views_node_feed_get_used_by($row['feedid']);
+    }
+    $feeds[$row['feedid']] = $row;
   }
+
+  return $feeds;
 }
 
-/**
- * themes the views_node_feed admin page
- *
- * @ingroup themeable
- */
-function theme_views_node_feed_admin($feeds) {
-  $output = '';
-  $output .= '<p>'. l(t('Add new node feed'), 'admin/settings/views_node_feed/edit/new') .'</p>';
-
-  $output .= '<p>';
-  if (count($feeds) == 0) {
-    $output .= t("No existing node feeds");
-  }
-  else {
-    $header = array(t('Identifier'), t('Actions'));
-    $rows = array();
-    foreach ($feeds as $ident) {
-      $rows[] = array($ident, l(t('Edit'), 'admin/settings/views_node_feed/edit/'. $ident) .' / '. l(t('Delete'), 'admin/settings/views_node_feed/delete/'. $ident));
+function views_node_feed_get_used_by($feedid) {
+  global $db_type;
+  $return = array();
+  $function = (($db_type == 'pgsql') ? 'STRPOS' : 'INSTR');
+  $sql = "
+    SELECT
+      vv.name,
+      vd.*
+    FROM
+      {views_display} as vd INNER JOIN
+      {views_view}    as vv ON(vd.vid = vv.vid)
+    WHERE
+      display_plugin = 'feed'
+      AND
+      {$function}(display_options, 'views_node_feed') <> 0
+    ORDER BY
+      vv.vid,
+      vd.display_title
+  ";
+  $dbr = db_query($sql);
+  while ($row = db_fetch_array($dbr)) {
+    $row['display_options'] = unserialize($row['display_options']);
+    if (
+      $row['display_options']['style_plugin'] == 'views_node_feed'
+      AND
+      $row['display_options']['style_options']['format'] == $feedid
+    ) {
+      $return[$row['vid']] = $row;
     }
-    $output .= theme('table', $header, $rows);
   }
-  $output .= '</p>';
+  return $return;
+}
 
-  return $output;
-}
\ No newline at end of file
Index: views_node_feed.views.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views_node_feed/Attic/views_node_feed.views.inc,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 views_node_feed.views.inc
--- views_node_feed.views.inc	7 Dec 2008 05:33:02 -0000	1.1.2.1
+++ views_node_feed.views.inc	15 Apr 2009 16:50:07 -0000
@@ -15,13 +15,13 @@ function views_node_feed_views_plugins()
     // 'module' => 'views_node_feed',
     'style' => array(
       'views_node_feed' => array(
-        'title' => t('Views Node Feed'),
-        'handler' => 'views_node_feed_plugin_style_feed',
-        'theme' => 'views_node_feed_view_feed',
+        'title'           => t('Views Node Feed'),
+        'handler'         => 'views_node_feed_plugin_style_feed',
+        'theme'           => 'views_node_feed_view_feed',
         'uses row plugin' => FALSE,
-        'uses options' => TRUE,
-        'type' => 'feed',
-        'help topic' => 'style-rss',
+        'uses options'    => TRUE,
+        'type'            => 'feed',
+        'help topic'      => 'style-rss',
       ),
     ),
   );
Index: views_node_feed_plugin_style_feed.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views_node_feed/Attic/views_node_feed_plugin_style_feed.inc,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 views_node_feed_plugin_style_feed.inc
--- views_node_feed_plugin_style_feed.inc	7 Dec 2008 05:33:02 -0000	1.1.2.1
+++ views_node_feed_plugin_style_feed.inc	15 Apr 2009 16:50:07 -0000
@@ -12,7 +12,8 @@ class views_node_feed_plugin_style_feed 
     $options['format'] = 'Feed';
   }
 
-  /*
+
+  /**
    * Provide a form for setting options.
    *
    * @param array $form
@@ -20,15 +21,19 @@ class views_node_feed_plugin_style_feed 
    */
   function options_form(&$form, &$form_state) {
     $form['format'] = array(
-      '#type' => 'select',
-      '#title' => t('Views Node Feed Template'),
-      '#options' => views_node_feed_get_feeds(),
+      '#type'          => 'select',
+      '#title'         => t('Views Node Feed Template'),
+      '#options'       => array(),
       '#default_value' => $this->options['format'],
     );
+    foreach (views_node_feed_get_feeds() as $feedid => $feed) {
+      $form['format']['#options'][$feedid] = $feed['title'];
+    }
   }
+
   function render() {
     $rows = array();
-    $feed = views_node_feed_get_feeds($this->options['format']);
+    $feed = views_node_feed_feed_load($this->options['format']);
     $nodes = array();
     foreach ($this->view->result as $row) {
       $node = node_load($row->nid);
