diff -urN publish_47/publish.info publish_5/publish.info
--- publish_47/publish.info	1969-12-31 19:00:00.000000000 -0500
+++ publish_5/publish.info	2007-06-11 18:24:19.526581928 -0400
@@ -0,0 +1,5 @@
+name = Publish
+description = Allow site to send content to other Drupal sites.
+version = 5.x-1.x-dev
+dependencies = taxonomy
+package = Publish
\ No newline at end of file
diff -urN publish_47/publish.install publish_5/publish.install
--- publish_47/publish.install	2006-12-08 14:49:14.000000000 -0500
+++ publish_5/publish.install	2007-06-11 18:24:19.519582992 -0400
@@ -12,7 +12,7 @@
         pub_vocab varchar(255) NOT NULL default '',
         UNIQUE KEY channel_id (channel_id,type)
         ) TYPE=MyISAM /*!40100 DEFAULT CHARACTER SET utf8 */;");
-
+        
       db_query("CREATE TABLE {publish_channel} (
         channel_id int(10) unsigned NOT NULL auto_increment,
         name varchar(255) NOT NULL default '',
@@ -26,6 +26,11 @@
         PRIMARY KEY  (channel_id)
         ) TYPE=MyISAM /*!40100 DEFAULT CHARACTER SET utf8 */;");
 
+			db_query("CREATE TABLE {publish_views} (
+				channel_id int(10) unsigned NOT NULL default '0',
+				view_name varchar(32) NOT NULL default '0'
+			) TYPE=MyISAM /*!40100 DEFAULT CHARACTER SET utf8 */;");
+			
       db_query("CREATE TABLE {publish_subscribers} (
         channel_id int(10) unsigned NOT NULL default '0',
         sid int(10) unsigned NOT NULL default '0',
@@ -52,18 +57,6 @@
         PRIMARY KEY (qid)
         ) TYPE=MyISAM /*!40100 DEFAULT CHARACTER SET utf8 */;");
       
-      db_query("CREATE TABLE {publish_cond} (
-        fid int(10) NOT NULL default '0',
-        channel_id int(10) NOT NULL default '0',
-        sid int(10) NOT NULL default '0',
-        field varchar(128) NOT NULL default '',
-        cond varchar(16) NOT NULL default '',
-        value varchar(255) NOT NULL default '',
-        PRIMARY KEY  (fid),
-        KEY channel_id (channel_id),
-        KEY sid (sid)
-        ) TYPE=MyISAM /*!40100 DEFAULT CHARACTER SET utf8 */;");
-
       db_query("CREATE TABLE {publish_vocab_map} (
         channel_id int(10) NOT NULL default '0',
         sid int(10) unsigned NOT NULL default '0',
@@ -105,4 +98,25 @@
   }
 
   return $ret;
+}
+
+function publish_update_3() {
+	switch($GLOBALS['db_type']) {
+		case 'mysql':
+		case 'mysqli':
+			$r = db_query("CREATE TABLE {publish_views} (
+				channel_id int(10) unsigned NOT NULL default '0',
+				view_name varchar(32) NOT NULL default '0'
+			) TYPE=MyISAM /*!40100 DEFAULT CHARACTER SET utf8 */;");
+			break;
+		case 'pgsql':
+			$r = FALSE;
+			break;
+	}
+	
+	if($r) {
+		drupal_set_message(t("Publish updated to integrate with views."));
+	} else {
+		drupal_set_message(t("Publish could not be updated to integrate with views. Perhaps you are running an unsupported database type."), 'error');
+	}
 }
\ No newline at end of file
diff -urN publish_47/publish.module publish_5/publish.module
--- publish_47/publish.module	2006-10-31 16:50:29.000000000 -0500
+++ publish_5/publish.module	2007-06-11 18:24:19.519582992 -0400
@@ -25,13 +25,11 @@
  */
 function publish_help($section) {
   switch ($section) {
-    case 'admin/modules#description':
-      return t('Allow site to send content to other Drupal sites.');
-    case 'admin/publish' :
+    case 'admin/build/publish' :
       return t('<p>Channels can be subscribed to by other Drupal sites using the subscribe module.<p>');
-    case strstr($section, 'admin/publish/pub/nodes'):
+    case strstr($section, 'admin/build/publish/pub/nodes'):
       return t('<p>Choose which which node types you would like to publish to other Drupal sites.</p>');
-    case strstr($section, 'admin/publish/pub/vocabularies'):
+    case strstr($section, 'admin/build/publish/pub/vocabularies'):
       return t('<p>Choose which vocabularies will accompany the nodes you publish to other Drupal sites. If a checkbox does not appear next to a node type it is because the node type is not associated with the vocabulary (you can change associations using administer &gt; categories &gt; edit vocabulary.)</p>');
   }
 }
@@ -40,73 +38,107 @@
  * Implementation of hook_menu().
  */
 function publish_menu($may_cache) {
+	$path = drupal_get_path('module', 'publish');
+	require_once("$path/publish_views.inc");
+	
   $items = array();
   $admin = user_access('administer channels');
 
   if (!$may_cache) {
-    if (arg(2) == 'pub' && is_numeric(arg(4))) {
-      $items[] = array(
-        'path' => 'admin/publish/pub/edit/' . arg(4),
-        'title' => t('edit'),
-        'callback' => 'publish_channel_edit',
-        'type' => MENU_CALLBACK,
-        'access' => $admin);
-    }
+    /**
+     * Subscribers.
+     */
     $items[] = array(
-      'path' =>'admin/publish/subscribers/' . arg(3),
-      'title' => t('subscribers'),
+      'path' =>'admin/build/publish/subscribers/' . arg(4),
+      'title' => t('Subscribers'),
       'callback' => 'publish_subscribers',
+      'callback arguments' => array(
+      	arg(4), // Channel ID
+      ),
       'type' => MENU_CALLBACK,
-      'access' => $admin);
-    $items[] = array('path' => 'admin/publish/filters/' . arg(3),
-      'title' => t('filters'),
-      'callback' => 'publish_channel_filter_form',
+      'access' => $admin,
+		);
+		
+	/**
+	 * Channel wizard.
+	 */
+   $items[] = array(
+     'path' => 'admin/build/publish/pub/edit',
+     'title' => t('Edit'),
+     'callback arguments' => array(
+				arg(5),													// Channel ID
+     ),
+     'callback' => 'publish_channel_edit',
+     'type' => MENU_CALLBACK,
+     'access' => $admin,
+		);
+    $items[] = array(
+      'path' => 'admin/build/publish/pub/vocabularies',
+      'title' => t('Vocabularies'),
+      'callback' => 'drupal_get_form',
+      'callback arguments' => array(
+				'publish_vocabulary_form',			// Form ID
+				arg(5), 												// Channel ID
+			),
       'type' => MENU_CALLBACK,
-      'access' => $admin);
-    $items[] = array('path' => 'admin/publish/edit/' . arg(4),
-      'title' => t('configure'),
-      'callback' => 'publish_channel_edit',
+      'access' => $admin,
+    );
+    $items[] = array(
+      'path' => 'admin/build/publish/pub/views',
+      'title' => t('Views'),
+      'callback' => 'publish_channel_views',
+      'callback arguments' => array(
+      	arg(5),													// Channel ID
+      ),
       'type' => MENU_CALLBACK,
-      'access' => $admin);
+      'access' => $admin,
+    );
+    $items[] = array(
+      'path' => 'admin/build/publish/pub/delete',
+      'title' => t('Delete'),
+      'callback' => 'drupal_get_form',
+      'callback arguments' => array(
+      	'publish_channel_delete_form',	// Form ID
+      	arg(5),													// Channel ID
+      ),
+      'type' => MENU_CALLBACK,
+      'access' => $admin,
+		);
   }
   else {
+  	/**
+  	 * Main UI.
+  	 */
     $items[] = array(
-      'path' => 'admin/publish',
-      'title' => t('publish'),
+      'path' => 'admin/build/publish',
+      'title' => t('Publish'),
       'callback' => 'publish_overview',
-      'access' => $admin);
-    $items[] = array(
-      'path' => 'admin/publish/pub/vocabularies',
-      'title' => t('vocabularies'),
-      'callback' => 'publish_vocabulary_form',
-      'type' => MENU_CALLBACK,
-      'access' => $admin);
+      'access' => $admin,
+		);
+		
+		/**
+		 * Tabs
+		 */
     $items[] = array(
-      'path' => 'admin/publish/list',
-      'title' => t('channels'),
+      'path' => 'admin/build/publish/list',
+      'title' => t('Channels'),
       'type' => MENU_DEFAULT_LOCAL_TASK,
       'weight' => -10,
       'callback' => 'publish_overview',
-      'access' => $admin);
+      'access' => $admin,
+		);
     $items[] = array(
-      'path' => 'admin/publish/add',
-      'title' => t('add channel'),
+      'path' => 'admin/build/publish/add',
+      'title' => t('Add channel'),
       'type' => MENU_LOCAL_TASK,
-      'callback' => 'publish_channel_form',
-      'access' => $admin);
-    $items[] = array(
-      'path' => 'admin/publish/pub/delete',
-      'title' => t('delete'),
-      'callback' => 'publish_channel_delete_form',
-      'type' => MENU_CALLBACK,
-      'access' => $admin);
-    $items[] = array(
-      'path' => 'admin/publish/pub/filters/delete',
-      'title' => t('filters'),
-      'callback' => 'publish_channel_filter_delete_form',
-      'type' => MENU_CALLBACK,
-      'access' => $admin);
+      'callback' => 'drupal_get_form',
+      'callback arguments' => array(
+      	'publish_channel_form',					// Form ID
+      ),
+      'access' => $admin,
+    );
   }
+
   return $items;
 }
 
@@ -114,7 +146,10 @@
 * Implementation of hook_perm().
 */
 function publish_perm() {
-  return array('subscribe to channels', 'administer channels');
+  return array(
+  	'subscribe to channels',
+  	'administer channels',
+  );
 }
 
 /********************************************************************
@@ -128,6 +163,9 @@
  *
  */
 function publish_cron() {
+	$path = drupal_get_path('module', 'publish');
+	require_once("$path/publish_views.inc");
+
   publish_push();
 }
 
@@ -141,33 +179,47 @@
   switch ($op) {
     case 'insert':
     case 'update':
-      // exit quickly if node is not in published state
-      if ($node->status != 1) {
-        return;
-      }
       if (PUBLISH_DEBUG_MODE) watchdog('publish', t('nodeapi firing'));
-      // Find all subscribers to this node.
-      $result = db_query("SELECT * FROM {publish_channel} p INNER JOIN {publish_nodetypes} n ON n.channel_id = p.channel_id INNER JOIN {publish_subscribers} s ON s.channel_id = p.channel_id WHERE n.type = '%s'", $node->type);
-      $exists = db_result(db_query("SELECT nid FROM {publish_queue} WHERE nid = %d", $node->nid));
-      if ($exists) { // delete older version from queue
-        db_query("DELETE FROM {publish_queue} WHERE nid = %d", $node->nid);
+      //Get all channels
+      $qs = db_query("SELECT pc.channel_id, pc.name FROM {publish_channel} pc WHERE pc.whenpub = 1");
+      while($obj = db_fetch_object($qs)) {
+      	$channels[$obj->channel_id] = $obj->name;
       }
-      $publish_now = FALSE;
-      while ($data = db_fetch_object($result)) {
-        if ($data->whenpub == PUBLISH_WHENPUB_NODESUB) {
-          $publish_now = TRUE;
-        }
-        // add them to the queue to have the node pushed out to them
-        // TODO: we should run the node through the channel's condition filters here?
-        db_query("INSERT INTO {publish_queue} (qid, nid, sid, channel_id, changed) VALUES (%d, %d, %d, %d, %d)", db_next_id('publish_queue'), $node->nid, $data->sid, $data->channel_id, $node->changed);
-        if (PUBLISH_DEBUG_MODE) watchdog('publish', t('channel %cid added node %nid to q for subscriber id %sid', array('%cid' => $data->channel_id, '%nid' => $node->nid, '%sid' => $data->sid)));
+
+      //Get all subscribers, keyed by channel_id and then by subscriber id.
+      $qs = db_query("SELECT ps.sid, ps.channel_id from {publish_subscribers} ps");
+      while($obj = db_fetch_object($qs)) {
+      	$subscribers[$obj->channel_id][$obj->sid] = $obj->sid;
       }
-      // set publish on exit if channel is set to publish at node submission time
-      if ($publish_now) {
-        if (PUBLISH_DEBUG_MODE) watchdog('publish', t('setting publish_exit'));
-        publish_exit(TRUE);
+
+      //Check to see if this node already exists in the publish queue. If it does, delete it.
+	    $exists = db_result(db_query("SELECT COUNT(pq.nid) FROM {publish_queue} pq WHERE pq.nid = %d", $node->nid));
+	    if($exists > 0) {
+	    	db_query("DELETE FROM {publish_queue} WHERE nid = %d", $node->nid);
+			}
+      
+      $publish_now = FALSE;
+      foreach($channels as $channel_id => $channel) {
+				$channel_subscribers = $subscribers[$channel_id];
+      	
+      	//Get all nodes of the channel.
+				$nodes = publish_get_nodes_by_channel($channel_id, 'nid');
+
+				//If the node is in the channel, add it to the queue for each subscriber.
+				if(array_key_exists($node->nid, (array)$nodes)) {
+					$publish_now = TRUE;
+      		foreach(array_keys((array)$channel_subscribers) as $sid) {
+						db_query("INSERT INTO {publish_queue} (qid, nid, sid, channel_id, changed) VALUES (%d, %d, %d, %d, %d)", db_next_id('publish_queue'), $node->nid, $sid, $channel_id, $node->changed);
+			      if (PUBLISH_DEBUG_MODE) watchdog('publish', t('channel !cid added node !nid to q for subscriber id !sid', array('!cid' => $channel_id, '!nid' => $node->nid, '!sid' => $sid)));
+  	    	}
+  	    }
       }
-      break;
+      
+			// Set publish on exit if channel is set to publish at node submission time
+    	if ($publish_now) {
+    	  if (PUBLISH_DEBUG_MODE) watchdog('publish', t('setting publish_exit'));
+    	  publish_exit(TRUE);
+    	}
   }
 }
 
@@ -197,14 +249,26 @@
  * Registering xml-rpc methods to callback functions.
  */
 function publish_xmlrpc() {
+	return array(
+		'drupal.publish.maySubscribe' => 'publish_xmls_may_subscribe',
+		'drupal.publish.subscribe' => 'publish_xmls_receive_subscription',
+		'drupal.publish.pull' => 'publish_xmls_publish',
+		'drupal.publish.getNode' => 'publish_xmls_get_node',
+		'drupal.publish.getChannels' => 'publish_xmls_get_channels',
+		'drupal.publish.cancelSubscription' => 'publish_xmls_cancel_subscription',
+	);
+	
+	/**
+	 * TODO: Update function signatures to match what we currently have.
   return array(
     array('drupal.publish.maySubscribe', 'publish_xmls_may_subscribe', array('array', 'int','string','string'), t('Return channel info if caller supplies appropriate credentials.')),
     array('drupal.publish.subscribe', 'publish_xmls_receive_subscription', array('int', 'int', 'string', 'string', 'string', 'string', 'array', 'array', 'array'), t('Establish relationship with subscriber.')),
-    array('drupal.publish.pull', 'publish_xmls_publish', array('array', 'int', 'int', 'string', 'string', 'array'), t('Send nodes matching certain conditions to subscriber.')),
+    array('drupal.publish.pull', 'publish_xmls_publish', array('array', 'int', 'int', 'string', 'string'), t('Send nodes matching certain conditions to subscriber.')),
     array('drupal.publish.getNode', 'publish_xmls_get_node', array('array', 'int', 'string', 'string', 'int'), t('Send single node to subscriber.')),
     array('drupal.publish.getChannels', 'publish_xmls_get_channels', array('array'), t('Return list of public channels on this site.')),
     array('drupal.publish.cancelSubscription', 'publish_xmls_cancel_subscription', array('boolean', 'int', 'string'), t('Cancel subscription.'))
   );
+  */
 }
 
 /********************************************************************
@@ -223,20 +287,20 @@
   $row = array();
   while ($data = db_fetch_object($result)) {
     $edit_items = array();
-    $edit_items[] = l(t('edit'), "admin/publish/pub/edit/$data->channel_id");
-    $edit_items[] = l(t('vocabularies'), "admin/publish/pub/vocabularies/$data->channel_id");
-    $edit_items[] = l(t('filters'), "admin/publish/filters/$data->channel_id");
+    $edit_items[] = l(t('edit'), "admin/build/publish/pub/edit/$data->channel_id");
+    $edit_items[] = l(t('vocabularies'), "admin/build/publish/pub/vocabularies/$data->channel_id");
+    $edit_items[] = l(t('views'), "admin/build/publish/pub/views/$data->channel_id");
     $count = db_result(db_query("SELECT COUNT(*) FROM {publish_subscribers} WHERE channel_id = %d", $data->channel_id));
-    $edit_items[] = l(t('delete'), "admin/publish/pub/delete/$data->channel_id");
+    $edit_items[] = l(t('delete'), "admin/build/publish/pub/delete/$data->channel_id");
     $row[] = array(
       array('data' => $data->channel_id, 'valign' => 'top'),
       array('data' => "$data->name", 'valign' => 'top'),
       array('data' => $data->advertise ? t('yes') : t('no'), 'valign' => 'top'),
-      array('data' => $count ? l($count, "admin/publish/subscribers/$data->channel_id") : t('none'), 'valign' => 'top'),
+      array('data' => $count ? l($count, "admin/build/publish/subscribers/$data->channel_id") : t('none'), 'valign' => 'top'),
       array('data' => implode("<br />\n", $edit_items)));
   }
 
-  $output = $row ? theme('table', $header, $row) : t('No channels created. Would you like to <a href="%add-channel">create one</a>?', array('%add-channel' => url('admin/publish/add')));
+  $output = $row ? theme('table', $header, $row) : t('No channels created. Would you like to <a href="!add-channel">create one</a>?', array('!add-channel' => url('admin/build/publish/add')));
 
   return $output;
 }
@@ -251,26 +315,147 @@
  *   An object representing a channel
  */
 function publish_channel_load($channel_id) {
+
   $channel = db_fetch_object(db_query('SELECT * FROM {publish_channel} WHERE channel_id = %d', $channel_id));
   if ($channel) {
-    $result = db_query('SELECT * FROM {publish_cond} WHERE channel_id = %d AND sid = 0', $channel_id);
-    $channel->filters = array();
-    while ($data = db_fetch_object($result)) {
-      $channel->filters[] = array('fid' => $data->fid, 'field' => $data->field, 'operator' => $data->cond, 'value' => $data->value);
-    }
+		$views = db_result(db_query("SELECT pv.view_name FROM {publish_views} pv WHERE pv.channel_id = %d", $channel_id));
+    $channel->views['view'] = $views;
+    $arguments = views_argument_api_get('publish_channel_' . $channel_id, array());
+    $channel->views['arguments'] = $arguments;
   }
 
   return $channel;
 }
 
-function publish_channel_edit() {
-  $channel_id = arg(4);
+function publish_channel_views($channel_id) {
+	$op = check_plain($_POST['op']);
+	$view_name = check_plain($_POST['channel_view']);
+	
+	if($op == t('Update')) {
+		publish_channel_view_save($channel_id, $view_name);
+	}
+	
+	$channel = publish_channel_load($channel_id);
+	
+	if(empty($channel)) {
+    drupal_set_message(t('No such channel.', 'error'));
+    drupal_goto('admin/build/publish');
+	} else {
+		return drupal_get_form('publish_channel_views_form', $channel);
+	}
+}
+
+function publish_channel_views_form($channel) {
+	//Todo: Good candidate for jQuery
+	
+	//Put together a views selector and an update button.
+	$form['channel_id'] = array(
+		'#type' => 'value',
+		'#value' => $channel->channel_id,
+	);
+	
+	$form['view'] = array(
+		'#type' => 'fieldset',
+		'#title' => t('View'),
+		'#collapsible' => FALSE,
+		'#collasped' => FALSE,
+	);
+	
+	$form['view']['channel_view'] = array(
+		'#title' => t('View'),
+		'#description' => t('Select a view to use with this channel.'),
+		'#type' => 'select',
+		'#default_value' => $channel->views['view'],
+		'#value' => $channel->views['view'],
+		'#options' => publish_get_views(),
+	);
+	$form['view']['channel_update'] = array(
+		'#type' => 'button',
+		'#value' => t('Update'),
+	);
+	
+	//Node types
+	$view = views_get_view($channel->views['view']);
+	$filters = $view->filter;
+	foreach((array)$filters as $filter) {
+		if($filter['field'] == 'node.type') {
+			$types = $filter['value'];
+		}
+	}
+	
+	if(empty($types)) {
+		foreach(node_get_types() as $type) {
+			$types[] = $type->type;
+		}
+	}
+	
+	$form['node_types'] = array(
+		'#type' => 'value',
+		'#value' => $types,
+	);
+	
+	$typemsg =  theme('item_list', $types);
+	
+	$form['node_types_message'] = array(
+		'#title' => t('Node types'),
+		'#description' => t('This channel currently uses a view that publishes nodes of the following types:'),
+		'#type' => 'fieldset',
+		'#collapsible' => TRUE,
+		'#collapsed' => FALSE,
+	);
+	
+	$form['node_types_message']['list'] = array(
+		'#type' => 'item',
+		'#value' => $typemsg,
+	);
+	
+	//Put together a place for arguments
+	$form['channel_arguments'] = array(
+		'#title' => t('View arguments'),
+		'#type' => 'fieldset',
+		'#collapsible' => TRUE,
+		'#collapsed' => FALSE,
+		'#theme' => 'views_argument_api_form_tabular',
+	);
+
+	$views_argument_api_form = views_argument_api_build_argument_form($channel->views['view']);
+	$views_argument_api_default_values = views_argument_api_get('publish_channel_' . $channel->channel_id, NULL);
+	
+	foreach($views_argument_api_form as $key => $element) {
+		$form['channel_arguments'][$key] = $element;
+		$form['channel_arguments'][$key]['#default_value'] = $views_argument_api_default_values[$key];
+	}
+	
+	$form['submit'] = array(
+		'#type' => 'submit',
+		'#value' => t('Submit'),
+	);
+	
+	return $form;
+}
+
+
+function publish_channel_views_form_submit($form_id, $form_values) {
+	//Save a channel's view.
+	publish_channel_view_save($form_values['channel_id'], $form_values['channel_view']);
+
+	//Save a channel's view arguments.
+	views_argument_api_save_arguments('publish_channel_' . $form_values['channel_id'], $form_values, $form_values['channel_view']);
+	
+	//Save the node type information
+  publish_node_save($form_values);
+
+	drupal_set_message(t('The channel was updated.'));
+	return 'admin/build/publish';
+}
+
+function publish_channel_edit($channel_id) {
   $channel = publish_channel_load($channel_id);
   if (!$channel) {
     drupal_set_message(t('No such channel.', 'error'));
-    drupal_goto('admin/publish');
+    drupal_goto('admin/build/publish');
   }
-  return publish_channel_form($channel);
+  return drupal_get_form('publish_channel_form', $channel);
 }
 
 /**
@@ -282,16 +467,9 @@
  *   Array with form values
  *
  * @return
- *   HTML output
+ *   An array of form elements.
  */
 function publish_channel_form($channel = NULL, $edit = array()) {
-  if (!isset($channel->name)) {
-    $output = '<h3>' . t('Adding channel') . '</h3>';
-  }
-  else {
-    $output = '<h3>' . t('Configuring channel') . ' "' . $channel->name . '"' . '</h3>';
-  }
-
   $form['name'] = array(
     '#type' => 'textfield',
     '#title' => t('Name'),
@@ -314,22 +492,6 @@
     '#description' => t('Show name and description of this channel when another site asks which channels are available.')
     );
 
-  $published = array();
-  $result = db_query("SELECT * FROM {publish_nodetypes} WHERE channel_id = '%s'", $channel->channel_id);
-  while ($data = db_fetch_object($result)) {
-    $published[] = $data->type;
-  }
-
-  $form['node_types'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Node types')
-    );
-  $form['node_types']['types'] = array(
-    '#type' => 'checkboxes',
-    '#title' => t('Publish the following node types'),
-    '#default_value' => $published,
-    '#options' => node_get_types(),
-    );
   $form['authentication'] = array(
     '#type' => 'fieldset',
     '#title' => t('Who may subscribe to this channel?')
@@ -338,7 +500,7 @@
     '#type' => 'radios',
     '#title' => t('Choose an authorization model'),
     '#default_value' => isset($channel->authtype) ? $channel->authtype : 'none',
-    '#options' =>  array(t('None'), t('Users with %perm permission', array('%perm' => theme('placeholder', 'subscribe to channel'))), t('Username and password (enter below)'))
+    '#options' =>  array(t('None'), t('Users with %perm permission', array('%perm' => 'subscribe to channel')), t('Username and password (enter below)'))
     );
   $form['authentication']['username'] = array(
     '#type' => 'textfield',
@@ -362,7 +524,8 @@
     '#type' => 'textarea',
     '#title' => t('Domains'),
     '#rows' => '2',
-    '#description' => t('Subscribers will be restricted to domains listed here, e.g. %example. If no domains are listed, all may subscribe.', array('%example' => theme('placeholder', 'example.org, example2.org')))
+    '#description' => t('Subscribers will be restricted to domains listed here, e.g. %example. If no domains are listed, all may subscribe.', array('%example' => 'example.org, example2.org')),
+    '#default_value' => $channel->domains,
     );
   $form['channel_id'] = array(
     '#type' => 'value',
@@ -382,7 +545,7 @@
     '#type' => 'submit',
     '#value' => t('Update Channel Settings')
     );
-  return drupal_get_form('publish_channel_form', $form);
+  return $form;
 }
 
 /**
@@ -416,9 +579,7 @@
       form_set_value($form['domains']['allowed'], ltrim($clean_domains, ','));
     }
   }
-  if (!array_filter($form_values['types'])) {
-    $errors['types'] = t('You must choose at least one node type to publish.');
-  }
+
   foreach ($errors as $name => $message) {
     form_set_error($name, $message);
   }
@@ -426,210 +587,19 @@
 
 function publish_channel_form_submit($form_id, $form_values) {
   // get an array of checked node types
-  $form_values['types'] = array_filter($form_values['types']);
   if ($form_values['channel_id']) {
     publish_channel_save($form_values);
   }
   else { // new channel
     $form_values['channel_id'] = publish_channel_save($form_values);
   }
-  publish_node_save($form_values);
-  return 'admin/publish';
-}
-
-/**
- * Menu callback. Build form for editing channel filters
- *
- * @param $edit
- *   Array with form values
- *
- * @return
- *   HTML output
- */
-function publish_channel_filter_form($edit = array()) {
-  $channel_id = arg(3);
-  $channel = publish_channel_load($channel_id);
-  if (!$channel) {
-    drupal_set_message(t('No such channel.'), 'error');
-    drupal_goto('admin/publish');
-  }
-  $form['field'] = array(
-    '#type' => 'select',
-    '#title' => t('Field'),
-    '#options' => publish_channel_filter_options()
-    );
-  foreach (publish_supported_operators() as $operator) {
-    $operators[$operator] = $operator;
-  }
-  $form['operation'] = array(
-    '#type' => 'select',
-    '#title' => t('Condition'),
-    '#options' => $operators
-    );
-  $form['value'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Value'),
-    '#size' => '25',
-    '#maxlength' => '254'
-    );
-  $form['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Add filter')
-    );
-  $form['channel_id'] = array(
-    '#type' => 'value',
-    '#value' => $channel_id);
-  return drupal_get_form('publish_channel_filter_form', $form);
-}
-
-function theme_publish_channel_filter_form($form) {
-  $channel = publish_channel_load($form['channel_id']['#value']);
-  if (count($channel->filters)) {
-    $output = t('The following filters are in effect for this channel:');
-    $header = array(t('Field'), t('Condition'), t('Value'), t('Operation'));
-    foreach ($channel->filters as $filter) {
-      $operation = l(t('delete'), 'admin/publish/pub/filters/delete/' . $channel->channel_id . '/' .$filter['fid']);
-      $rows[] = array(
-        array('data' => $filter['field']),
-        array('data' => $filter['condition']),
-        array('data' => $filter['value']),
-        array('data' => $operation)
-        );
-    }
-    $output = theme('table', $header, $rows);
-  }
-  else {
-    $output = t('No filters are currently defined.');
-  }
-
-  // we don't want theming so we do a table the old-fashioned way
-  $output .= '<table><tr>';
-  $output .= '<td>' . form_render($form['field']) . '<td>';
-  $output .= '<td>' . form_render($form['operation']) . '<td>';
-  $output .= '<td>' . form_render($form['value']) . '<td>';
-  $output .= '<td>' . form_render($form['submit']) . '</td>';
-  $output .= '</tr></table>';
-  $output .= form_render($form);
-
-  return $output;
-}
-
-function publish_channel_filter_options() {
-  $v_names = array();
-  if (module_exist('taxonomy')) {
-    $vocabularies = taxonomy_get_vocabularies();
-    foreach ($vocabularies as $v) {
-      $v_names[$v->vid] = $v->name;
-    }
-  }
-  $merged = array_merge($v_names, publish_supported_fields());
-  foreach ($merged as $name) {
-    $options[$name] = $name;
-  }
-  return $options;
-}
-
-function publish_channel_filter_form_validate($form_id, $edit) {
-  $errors = array();
-
-  if ($edit['field'] == '') {
-    $errors['field'] = t('Please choose a field.');
-  }
-  elseif (!array_key_exists($edit['field'], publish_channel_filter_options())) {
-    $errors['field'] = t('Invalid field.');
-  }
-
-  if (!in_array($edit['operation'], publish_supported_operators())) {
-    $errors['operation'] = t('Invalid condition.');
-  }
-
-  foreach ($errors as $name => $message) {
-    form_set_error($name, $message);
-  }
-}
-
-function publish_channel_filter_form_submit($form_id, $form_values) {
-  $channel = publish_channel_load($form_values['channel_id']);
-  publish_channel_filter_save($channel, $form_values);
-  drupal_set_message(t('Filter added.'));
-  return 'admin/publish/filters/' . $form_values['channel_id'];
-}
-
-function publish_channel_filter_save(&$channel, $edit = array()) {
-  $options = publish_channel_filter_options();
-  $field = $options[$edit['field']];
-  $condition = $edit['operation'];
-  $value = $edit['value'];
-  // get the new field, condition and value from the form
-  // validate them (make sure they're not already in
-  if (!isset($channel->filters)) {
-    $channel->filters = array();
-  }
-  $duplicate = FALSE;
-  foreach ($channel->filters as $filter) {
-    if (($filter['field'] == $field) && ($filter['condition'] == $condition) && ($filter['value'] == $value)) {
-      $duplicate = TRUE;
-    }
-  }
-  if (!$duplicate) {
-    $fid = db_next_id('publish_filter');
-    $channel->filters[] = array('fid' => $fid, 'field' => $field, 'condition' => $condition, 'value' => $value);
-    // the insertion of 0 into the sid (subscription id) field denotes
-    // that this condition is a local channel condition
-    db_query("INSERT INTO {publish_cond} (fid, channel_id, sid, field, cond, value) VALUES (%d, %d, 0, '%s', '%s', '%s')", $fid, $channel->channel_id, $field, $condition, $value);
-  }
-  else {
-    drupal_set_message(t('This filter already exists.'), 'error');
-  }
+  return 'admin/build/publish';
 }
 
-function publish_channel_filter_delete_form() {
-  $channel_id = arg(5);
-  $filter_id = arg(6);
-  $channel = publish_channel_load($channel_id);
-  if (!$channel) {
-    drupal_set_message(t('No such channel.', 'error'));
-    drupal_goto('admin/publish');
-  }
-  $form['channel_id'] = array('#type' => 'value', '#value' => $channel_id);
-  $form['filter_id'] = array('#type' => 'value', '#value' => $filter_id);
-  $output = confirm_form('publish_channel_filter_delete_form', $form,
-                   t('Are you sure you want to delete this filter?'),
-                   'admin/publish', t('This action cannot be undone.'),
-                   t('Delete'), t('Cancel')  );
-  return $output;
-}
-
-function publish_channel_filter_delete_form_submit($form_id, $form_values) {
-  publish_channel_filter_delete($form_values['channel_id'], $form_values['filter_id']);
-  return 'admin/publish/filters/' . $form_values['channel_id'];
-}
-function publish_channel_filter_delete($channel_id, $fid) {
-  $data = db_fetch_object(db_query('SELECT pc.field, pc.cond, pc.value, pp.name FROM {publish_cond} as pc, {publish_channel} as pp WHERE pc.fid = %d AND pp.channel_id = %d', $fid, $channel_id));
-  $filtertext = $data->field . ' ' . $data->cond . ' ' . $data->value;
-  db_query('DELETE FROM {publish_cond} WHERE fid = %d', $fid);
-  watchdog('special', t('Deleted filter %filter from channel %name.', array('%filter' => theme('placeholder', $filtertext), '%name' => $data->name)));
-  drupal_set_message(t('Deleted filter %filter.', array('%filter' => theme('placeholder', $filtertext))));
-}
-
-/**
- * Load list of publishable node types from the database.
- *
- * @param $channel_id
- *   The ID of the channel in question.
- *
- * @return
- *   An array with node types as keys
- */
-function publish_nodetypes_load($channel_id) {
-  $types = array();
-
-  $result = db_query('SELECT type FROM {publish_nodetypes} WHERE channel_id = %d', $channel_id);
-  while ($data = db_fetch_object($result)) {
-    $types[$data->type] = $data->type;
-  }
-
-  return $types;
+function publish_channel_view_save($channel_id, $view_name) {
+	db_query("DELETE FROM {publish_views} WHERE channel_id = %d", $channel_id);
+	$r = db_query("INSERT INTO {publish_views} (channel_id, view_name) VALUES (%d, '%s')", $channel_id, $view_name);
+	return $r;
 }
 
 /**
@@ -638,7 +608,8 @@
  * @param $edit
  */
 function publish_channel_save($edit) {
-  if (!$edit['clean_domains']) $edit['clean_domains'] = '';
+//  if (!$edit['clean_domains']) $edit['clean_domains'] = '';
+	$edit['domains'] = $edit['allowed'];
   $channel_id = $edit['channel_id'];
   $fields = publish_db_fields('publish_channel');
 
@@ -652,8 +623,8 @@
       }
     }
     db_query("UPDATE {publish_channel} SET ". implode(', ', $q) ." WHERE channel_id = ". db_escape_string($edit['channel_id']), $v);
-     watchdog('special', t('%type: updated channel %name', array('%type' => '<em>'. t('publish') .'</em>', '%name' => "<em>" . $edit['name'] . "</em>")));
-    drupal_set_message(t('Updated channel %name', array('%name' => theme('placeholder', $edit['name']))));
+     watchdog('special', t('%type: updated channel %name', array('%type' => t('publish'), '%name' => $edit['name'])));
+    drupal_set_message(t('Updated channel %name', array('%name' => $edit['name'])));
   }
   else {
     // create new channel
@@ -672,35 +643,32 @@
     // Insert the node into the database:
     $query = "INSERT INTO {publish_channel} (". implode(", ", $k) .") VALUES(". implode(", ", $s) .")";
     db_query($query, $v);
-    watchdog('special', t('%type: created channel %name.', array('%type' => '<em>'. t('publish') .'</em>', '%name' => "<em>" . $edit['name'] . "</em>")));
-    drupal_set_message(t('Created channel %name', array('%name' => theme('placeholder', $edit['name']))));
+    watchdog('special', t('!type: created channel !name.', array('!type' => t('publish'), '!name' => $edit['name'])));
+    drupal_set_message(t('Created channel !name', array('!name' => $edit['name'])));
   }
   return $edit['channel_id'];
 }
 
 /**
- * Menu callback.
- * The HTML form to confirm deletion of a channel.
+ * The form to confirm deletion of a channel.
  */
-function publish_channel_delete_form() {
-  $channel_id = arg(4);
-  $channel = publish_channel_load($channel_id);
+function publish_channel_delete_form($channel_id) {
+	$channel = publish_channel_load($channel_id);
   if (!$channel) {
     drupal_set_message(t('No such channel.', 'error'));
-    drupal_goto('admin/publish');
+    drupal_goto('admin/build/publish');
   }
+
   $form['channel_id'] = array('#type' => 'value', '#value' => $channel_id);
-  $output = confirm_form('publish_delete_form', $form,
-                   t('Are you sure you want to delete %title?', array('%title' => theme('placeholder', $channel->name))),
-                   'admin/publish', t('This action cannot be undone.'),
-                   t('Delete'), t('Cancel')  );
-  return $output;
+
+  return confirm_form($form, t('Are you sure you want to delete %title?', array('%title' => $channel->name)), 'admin/build/publish', t('This action cannot be undone.'), t('Delete'), t('Cancel'), 'publish_channel_delete_form');
+
 }
 
-function publish_delete_form_submit($form_id, $form_values) {
+function publish_channel_delete_form_submit($form_id, $form_values) {
   $channel = publish_channel_load($form_values['channel_id']);
   publish_channel_delete($channel);
-  return 'admin/publish';
+  return 'admin/build/publish';
 }
 
 /**
@@ -711,71 +679,18 @@
  */
 function publish_channel_delete($channel) {
   db_query('DELETE FROM {publish_channel} WHERE channel_id = %d', $channel->channel_id);
-  db_query("DELETE FROM {publish_nodetypes} WHERE channel_id = '%s'", $channel->channel_id);
-  db_query('DELETE FROM {publish_cond} WHERE channel_id = %d', $channel->channel_id);
 
   watchdog('publish', t('deleted channel %name.', array('%name' => $channel->name)));
 }
 
-
-/**
- * Form to set the publish settings for node types.
- */
-function publish_node_form($channel_id, $edit = array()) {
-
-  $nodetypes = array();
-  foreach (node_list() as $type) {
-    $nodetypes[$type] = node_invoke($type, 'node_name');
-  }
-
-  $published = array();
-  $result = db_query("SELECT * FROM {publish_nodetypes} WHERE channel_id = '%s'", $channel_id);
-  while ($data = db_fetch_object($result)) {
-    $published[] = $data->type;
-  }
-
-
-  $node_checkboxes = '';
-  foreach ($nodetypes as $internal_type => $type) {
-    $node_checkboxes .= form_checkbox($type, 'pub_' . $internal_type, $internal_type, in_array($internal_type, $published));
-  }
-
-  $output = form_group(t('Publish the following node types'), $node_checkboxes);
-  $output .= form_hidden('channel_id', $channel_id);
-
-  return $output;
-}
-
 /**
  * Save a nodetype config data to the database.
  */
 function publish_node_save($edit) {
-
+	
   $channel_id = $edit['channel_id'];
-  $submitted_nodetypes = $edit['types'];
-
-  /*
+  $submitted_nodetypes = $edit['node_types'];
 
-  $nodetypes = array();
-  foreach (node_list() as $type) {
-    $nodetypes[$type] = node_invoke($type, 'node_name');
-    if ($edit['pub_' . $type]) {
-      $submitted_nodetypes[$type] = $type;
-    }
-  }
-
-  $result = db_query("SELECT * FROM {publish_nodetypes} WHERE channel_id = '%s'", $channel_id);
-  while ($data = db_fetch_object($result)) {
-    if (key_exists($data->type, $submitted_nodetypes)) {
-      // node type exists in database and has been checked; no change so delete from array
-      unset($submitted_nodetypes[$data->type]);
-    }
-    else {
-      // node type exists in database but not checked; delete from database
-      db_query("DELETE FROM {publish_nodetypes} WHERE type = '%s'", $data->type);
-    }
-  }
-  */
   db_query("DELETE FROM {publish_nodetypes} WHERE channel_id = %d", $channel_id);
 
   // now we are left with the node types to add
@@ -792,12 +707,7 @@
   $channel = publish_channel_load($channel_id);
   if (!$channel) {
     drupal_set_message(t('No such channel.', 'error'));
-    drupal_goto('admin/publish');
-  }
-
-  if (!module_exist('taxonomy')) {
-    drupal_set_message(t('The taxonomy module is disabled. Please enable the taxonomy module.'), 'warning');
-    drupal_goto('/admin/publish');
+    drupal_goto('admin/build/publish');
   }
 
   $vocabularies = taxonomy_get_vocabularies();
@@ -842,7 +752,7 @@
             '#name' => 'edit[' . $type . '|' . $v->name . ']',
             '#return_value' => 1
             );
-          $s = form_render($form[$type . '|' . $v->name]);
+          $s = drupal_render($form[$type . '|' . $v->name]);
         }
         $table .= '<td>' . $s . '</td>';
       }
@@ -864,10 +774,15 @@
   else {
     // no node types have been chosen for publication
     drupal_set_message(t('No node types have been chosen for publication. Edit channel and choose at least one node type.'));
-    drupal_goto('/admin/publish');
+    drupal_goto('/admin/build/publish');
   }
 
-  return drupal_get_form('publish_vocabulary_form', $form);
+	$form['return'] = array(
+		'#type' => 'item',
+		'#value' => l(t('Return to Publish'), 'admin/build/publish/'),
+	);
+	
+  return $form;
 }
 
 /**
@@ -900,9 +815,9 @@
     db_query("INSERT INTO {publish_nodetypes} (channel_id, type, pub_vocab) VALUES ('%s', '%s', '%s')", $channel_id, $type, serialize($vocs_this_node));
   }
   $channel = publish_channel_load($channel_id);
-  drupal_set_message(t("Saved vocabulary publication configuration for channel %name.", array('%name' => theme('placeholder', $channel->name))));
+  drupal_set_message(t("Saved vocabulary publication configuration for channel %name.", array('%name' => $channel->name)));
 
-  return 'admin/publish';
+  return 'admin/build/publish';
 }
 
 /**
@@ -940,7 +855,9 @@
   static $nodetypes = array();
   static $published_vocabularies = array();
 
-  $lookup = node_get_types();
+  foreach(node_get_types() as $type) {
+  	$lookup[$type->type] = $type->name;
+  }
   $result = db_query("SELECT * FROM {publish_nodetypes} WHERE channel_id = '%s'", $channel_id);
   while ($data = db_fetch_object($result)) {
     $nodetypes[$data->type] = $lookup[$data->type];
@@ -964,8 +881,7 @@
   * @return
   *   an HTML table of subscribers and related information
   */
- function publish_subscribers () {
-   $channel_id = arg(3);
+ function publish_subscribers($channel_id) {
    $channel = publish_channel_load($channel_id);
    $output = '<h3>' . t('Subscribers to channel') . " '$channel->name':</h3>";
     $header = array(array('data' => t('Subscriber')), array('data' => t('Status')), array('data' => 'Operations', 'colspan' => '1'));
@@ -982,73 +898,16 @@
  }
 
 /**
- * Compile array of publishable nodes according to given conditions.
+ * Compile array of publishable nodes.
  *
  * @param $channel_id
  *   The ID of the channel in question.
  *
- * @param $cond
- *   Array of triplet arrays containing field, condition, value.
- *   Example: array(array('created', '>', '0'))
- *   Example: array(array('created', '>', '0'), array('nid', '<', '5'))
- *
  * @return
  *   An array of node objects.
  */
-function publish_publish($channel_id, $cond) {
-  static $channels = array();
-
-  if (isset($channels[$channel_id])) {
-    $channel = $channels[$channel_id];
-  }
-  else {
-    $channel = publish_channel_load($channel_id);
-    $channels[$channel_id] = $channel;
-  }
-  $node_ids = array();
-  $published_types = publish_nodetypes_load($channel_id);
-  if (!$published_types) return array();
-
-  $where = '';
-  foreach ($published_types as $type) {
-    $where .= "OR type = '" . (function_exists('db_escape_string') ? db_escape_string($type) : check_query($type)) . "' ";
-  }
-  // strip off leading 'OR '
-  $where = $where ? '(' . strstr($where, " ") . ')' : '';
-
-  list($clean_cond, $taxonomy_cond) = publish_cond_validate(array_merge($channel->filters, $cond));
-  $filter = array();
-
-  foreach ($clean_cond as $triplet) {
-    $field = $triplet['field'];
-    $operator = $triplet['operator'];
-    $value = $triplet['value'];
-
-    // check if value is numeric. If not, put single quotes around it and clean it
-    $quot_start  = ' ';
-    $quot_end    = ' ';
-    $clean_value = null;;
-
-    if (!is_numeric($value)) {
-      $quot_start = " '";
-      $quot_end   = "' ";
-      $clean_value = function_exists('db_escape_string') ? db_escape_string($value) : check_query($value);
-    }
-
-    $filter[] = $field . ' ' . $operator . $quot_start . ($clean_value ? $clean_value : $value) . $quot_end;
-  }
-
-  if ($filter) {
-    $where .= $filter[1] ? implode($filter, ' AND') : ' AND ' . $filter[0];
-  }
-
-  $query = "SELECT nid FROM {node} WHERE $where";
-  $result = db_query($query);
-  while ($data = db_fetch_object($result)) {
-    $node_ids[] = $data->nid;
-  }
-
-  return _publish_publish($node_ids, $taxonomy_cond);
+function publish_publish($channel_id) {
+	return publish_get_nodes_by_channel($channel_id);
 }
 
 /**
@@ -1071,76 +930,57 @@
   // qtime should be long enough that an attempt to send each item
   // in the queue can be made within the time window
   // we use db_fetch_object() to get one node at a time
-  while ($data = db_fetch_object(db_query("SELECT * FROM {publish_queue} WHERE last_attempt < %d ORDER BY changed", time() - $qtime))) {
-    if (PUBLISH_DEBUG_MODE) watchdog('publish', t('beginning push for channel %channel, subscriber %subscriber', array('%channel' => $data->channel_id, '%subscriber' => $data->sid)));
-
-    // see if there are any other nodes we can include for this subscriber
-    // while we have the overhead of sending xmlrpc anyway
-    $node_ids = array();
-    $qids = array();
-    $result = db_query("SELECT qid, nid, attempts FROM {publish_queue} WHERE sid = %d AND channel_id = %d", $data->sid, $data->channel_id);
-    while ($row = db_fetch_object($result)) {
-      if (PUBLISH_DEBUG_MODE) watchdog('publish', t('preparing to push qid %qid; nid %nid', array('%qid' => $row->qid, '%nid' => $row->nid)));
-      $node_ids[] = $row->nid;
-      $qids[$row->nid] = array('qid' => $row->qid, 'attempts' => $row->attempts);
-    }
-    $nodes = array();
-    foreach ($node_ids as $nid) {
-      // run the nodes through the channel's condition filters
-      // note that if push is happening from nodeapi insert/update (not cron),
-      // _publish_publish is doing a node_load before modules after us
-      // have had a chance to respond to the nodeapi insert/update
-      // TODO: need to include the subscription's optional condition filters here;
-      // currently we ignore them (channel-specific filters are handled in publish_publish())
-      $survived_filter = publish_publish($data->channel_id, array(array('field' => 'nid', 'operator' => '=', 'value' => $nid)));
-      if ($survived_filter) {
-        if (PUBLISH_DEBUG_MODE) watchdog('publish', t('keeping node %nid', array('%nid' => $nid)));
-        $nodes = array_merge($nodes, $survived_filter);
-      }
-      else { // this node did not pass conditions for this channel
-        //      and thus will never be sent; delete it from the queue
-        if (PUBLISH_DEBUG_MODE) watchdog('publish', t('removing filtered node %nid from queue', array('%nid' => nid)));
-        db_query("DELETE FROM {publish_queue} WHERE qid = %d", $qids[$nid]['qid']);
-      }
-    }
-
-    // we've got the nodes, now push them out
-    $subscription = publish_subscriptions_load($data->sid);
-    $message = array(
-      'token'     => $subscription->token,
-      'rsid'      => (int)$subscription->sid,
-      'count'     => count($nodes),
-      'site_url'  => $base_url,
-      'site_name' => variable_get('site_name', 'drupal'),
-      'nodes'     => $nodes
-      );
-
-    $response = xmlrpc($subscription->url, 'drupal.subscribe.receive', $message);
-    if ($response) {
-      // we have successfully published the pending nodes for this channel to this subscriber
-      // thus, delete them from the queue
-      foreach ($nodes as $node) {
-        if (PUBLISH_DEBUG_MODE) watchdog('publish', t('removing node %nid from queue (qid %qid)', array('%nid' => $node->nid, '%qid' => $qids[$node->nid]['qid'])));
-        db_query("DELETE FROM {publish_queue} WHERE qid = %d", $qids[$node->nid]['qid']);
-      }
-      watchdog('publish', t('XMLRPC pushed %count nodes to %url (channel id %channel_id)', array('%count' => $message['count'], '%url' => check_plain($subscription->url), '%channel_id' => check_plain($data->channel_id))));
-    }
-    else { // push failed
-      $error = xmlrpc_error_msg();
-      foreach ($node_ids as $nid) {
-        $attempts = $qids[$nid]['attempts'];
-        $max_attempts = variable_get('publish_push_max_attempts', 5);
-        if ($attempts > $max_attempts) {
-          if (PUBLISH_DEBUG_MODE) watchdog('publish', t('max of %attempts attempts exceeded; removing node %nid from queue', array('%attempts' => $max_attempts, '%nid' => $node->nid)));
-          db_query("DELETE FROM {publish_queue} WHERE qid = %d", $qids[$nid]['qid']);
-        }
-        else {
-          db_query("UPDATE {publish_queue} SET attempts = %d, last_attempt = %d WHERE qid = %d", $attempts + 1, time(), $qids[$nid]['qid']);
-        }
-      }
-      watchdog('publish', t('XMLRPC push failed for %url (channel id %channel_id): %faultString', array('%url' => theme('placeholder', $subscription->url), '%channel_id' => theme('placeholder', $data->channel_id), '%faultString' => $error ? $error : t('unavailable'))), WATCHDOG_ERROR);
-    }
-  }
+  $qs = db_query("SELECT * FROM {publish_queue} WHERE last_attempt < %d ORDER BY changed", time() - $qtime);
+  while ($data = db_fetch_object($qs)) {
+  	$queue[$data->channel_id][$data->sid][$data->nid] = $data;
+  }
+
+  foreach($queue as $channel_id => $channel) {
+  	$channel_nodes = publish_get_nodes_by_channel($channel_id, 'nid');
+  	
+  	foreach($channel as $sid => $queue_items) {
+    	if (PUBLISH_DEBUG_MODE) watchdog('publish', t('beginning push for channel %channel, subscriber %subscriber', array('%channel' => $channel_id, '%subscriber' => $sid)));
+    	
+    	foreach($queue_items as $queue_item) {
+    		$nodes[$queue_item->nid] = $channel_nodes[$queue_item->nid];
+    	}
+    	
+    	// we've got the nodes, now push them out
+    	$subscription = publish_subscriptions_load($sid);
+    	$message = array(
+    	  'token'     => $subscription->token,
+    	  'rsid'      => (int)$subscription->sid,
+    	  'count'     => count($nodes),
+    	  'site_url'  => $base_url,
+    	  'site_name' => variable_get('site_name', 'drupal'),
+    	  'nodes'     => $nodes
+    	  );
+    	
+    	$response = xmlrpc($subscription->url, 'drupal.subscribe.receive', $message);
+    	if ($response) {
+    	  // we have successfully published the pending nodes for this channel to this subscriber
+    	  // thus, delete them from the queue
+   	    if (PUBLISH_DEBUG_MODE) watchdog('publish', t('removing node %nid from queue (qid %qid)', array('%nid' => $node->nid, '%qid' => $queue_items[$node->nid]->qid)));
+   	    db_query("DELETE FROM {publish_queue} WHERE channel_id = %d AND sid = %d", $channel_id, $sid);
+    	  watchdog('publish', t('XMLRPC pushed !count nodes to !url (channel id !channel_id)', array('!count' => $message['count'], '!url' => check_plain($subscription->url), '!channel_id' => check_plain($channel_id))));
+    	}
+    	else { // push failed
+    	  $error = xmlrpc_error_msg();
+    	  foreach ($nodes as $nid => $node) {
+    	    $attempts = $queue_items[$nid]->attempts;
+    	    $max_attempts = variable_get('publish_push_max_attempts', 5);
+    	    if ($attempts > $max_attempts) {
+    	      if (PUBLISH_DEBUG_MODE) watchdog('publish', t('max of !attempts attempts exceeded; removing node !nid from queue', array('!attempts' => $max_attempts, '!nid' => $node->nid)));
+    	      db_query("DELETE FROM {publish_queue} WHERE qid = %d", $queue_items[$nid]->qid);
+    	    }
+    	    else {
+    	      db_query("UPDATE {publish_queue} SET attempts = %d, last_attempt = %d WHERE qid = %d", $attempts + 1, time(), $queue_items[$nid]->qid);
+    	    }
+    	  }
+    	  watchdog('publish', t('XMLRPC push failed for %url (channel id %channel_id): %faultString', array('%url' => $subscription->url, '%channel_id' => $channel_id, '%faultString' => $error ? $error : t('unavailable'))), WATCHDOG_ERROR);
+    	}
+  	}
+	}
 }
 
 /********************************************************************
@@ -1247,7 +1087,7 @@
   }
 
   $who = $username? check_plain($username) : t('anonymous');
-  watchdog('publish', t('XML-RPC: may subscribe to channel %channel_id? %name (%link).', array('%channel_id' => $channel_id, '%name' => "<em>$who</em>", '%link' => "<em>$host</em>")));
+  watchdog('publish', t('XML-RPC: may subscribe to channel !channel_id? %name (%link).', array('!channel_id' => $channel_id, '%name' => $who, '%link' => $host)));
 
   return $response;
 }
@@ -1264,14 +1104,12 @@
  * @param
  *  $dest the XMLRPC endpoint on the client to which publishing site
  *    may publish nodes
- * @param
- *  $cond array of condition triplets; see publish_publish()
  *
  * @return
  *   An array containing a status message and the subscription id on the publishing site.
  */
- function publish_xmls_receive_subscription($channel_id, $username, $pass, $dest, $method, $remote_vids, $local_vids, $cond) {
-
+ function publish_xmls_receive_subscription($channel_id, $username, $pass, $dest, $method, $remote_vids, $local_vids) {
+	
   $host = gethostbyaddr($_SERVER['REMOTE_ADDR']);
 
   // should check if $dest is in domain of $host here
@@ -1314,14 +1152,12 @@
  *   $username (string)
  * @param
  *   $password (string)
- * @param
- *   $cond (array of condition triplets; see publish_publish() )
  *
  * @return
  *   An array of node objects keyed by node id.
  */
- function publish_xmls_publish($channel_id, $sid, $username, $pass, $cond) {
-
+ function publish_xmls_publish($channel_id, $sid, $username, $pass) {
+//MS: watchdog('publish-ms', 'channel_id: ' . $channel_id . ' | sid: ' . $sid . ' | username: ' . $username . ' | pass: ' . $pass);
   $ip = $_SERVER['REMOTE_ADDR'];
   $host = gethostbyaddr($ip);
 
@@ -1331,9 +1167,8 @@
   }
   if ($channel) {
     $may_subscribe = publish_may_subscribe($channel, $username, $pass, $host);
-
     if ($may_subscribe && (publish_subscription_validate($sid))) {
-      $nodes = publish_publish($channel_id, $cond);
+      $nodes = publish_publish($channel_id);
       global $base_url;
 
       $response = array(
@@ -1382,6 +1217,87 @@
  * Module Functions :: Private
  ********************************************************************/
 
+/**
+ * Returns a list of views, including default views.
+ * @return
+ *	An array of view names, keyed by view name.
+ */
+function publish_get_views() {
+	$views = array();
+	$qs = db_query("SELECT v.vid, v.name FROM {view_view} v");
+	while($obj = db_fetch_object($qs)) {
+		$views[$obj->name] = $obj->name;
+	}
+  $default_views = module_invoke_all('views_default_views');
+	foreach($default_views as $default_view) {
+		$views[$default_view->name] = $default_view->name;
+	}
+
+	return $views;
+}
+
+/**
+ * Returns a list of nodes for a given channel.
+ *
+ * @param $channel_id
+ *	A numeric channel_id.
+ * @param $key
+ *	'nid' to key by node IDs. Otherwise, NULL.
+ * @return
+ *	An array of nodes, in the proper format to be published.
+ */
+function publish_get_nodes_by_channel($channel_id, $key = NULL) {
+  //Include this here so that we can work with the queries.
+  $path = drupal_get_path('module', 'views');
+  require_once("./$path/views_query.inc");
+
+	$channel = publish_channel_load($channel_id);
+	if(!empty($channel)) {
+		$api_id = 'publish_channel_' . $channel_id;
+		$default = array();
+		$view_name = $channel->views['view'];
+		$for_view = TRUE;
+
+		$args = views_argument_api_get_processed($api_id, $default, $view_name, $for_view);
+		$view = views_get_view($view_name);
+		$filters = array();
+		$queries = _views_build_query($view, $args);
+
+		$query = $queries['query'];
+		$qs = call_user_func_array('db_query', array_merge(array($queries['query']), $queries['args']));
+		while($obj = db_fetch_object($qs)) {
+			$node = node_load($obj->nid);
+			unset($node->data);
+    	unset($node->revisions);
+    	unset($node->picture);
+    	unset($node->workspaces);
+    	$node->url = url('node/' . $node->nid, NULL, NULL, TRUE);
+	    
+	    // we need to add vocabulary information ourselves, per the settings in the channel
+  	  $taxonomy_terms = taxonomy_node_get_terms($node->nid);
+  	  $published_vocabularies = publish_node_vocabularies($channel_id);
+  	  $published_vocabularies = array_pop($published_vocabularies);
+  	  $published_vocabularies = array_keys((array)$published_vocabularies[$node->type]);
+  	  
+  	  foreach($taxonomy_terms as $term) {
+  	  	if(in_array($term->vid, $published_vocabularies)) {
+  	  		$terms[$term->tid] = $term;
+  	  	}
+  	  }
+  	  $node->taxonomy_terms = $terms;
+  	  
+  	  if($key == 'nid') {
+ 				$nodes[$node->nid] = $node;
+ 			} else {
+ 				$nodes[] = $node;
+ 			}
+		}
+	} else {
+		$nodes = array();
+	}
+	
+	return $nodes;
+}
 
 /**
  * Return an array of all vocabulary objects.
@@ -1470,57 +1386,8 @@
 function publish_db_fields($table_name) {
   switch ($table_name) {
     case 'publish_channel':
-      return array('channel_id', 'name', 'description', 'advertise', 'authtype', 'whenpub', 'username', 'pass', 'domain');
-  }
-}
-
-/**
- * Instantiate some nodes and remove some unwanted properties.
- *
- * @param $node_ids
- *   Array of node IDs to instantiate
- * @param $cond
- *   Array of triplets representing a filter (only vocabulary filters apply here)
- *
- * @return
- *   An array of node objects.
- */
- function _publish_publish($node_ids = array(), $cond) {
-  $nodes = array();
-  foreach ($node_ids as $nid) {
-    $node = node_load(array('nid' => $nid));
-    unset($node->data);
-    unset($node->revisions);
-    unset($node->picture);
-    unset($node->workspaces);
-    $node->url = url('node/' . $nid, NULL, NULL, TRUE);
-
-    // we need to add vocabulary information ourselves
-    $node->taxonomy_terms = taxonomy_node_get_terms($node->nid);
-
-    if ($cond) {
-      // implement field = value
-      $conditions_met = FALSE;
-      foreach ($cond as $triplet) {
-        switch ($triplet['operator']) {
-          case '=':
-            foreach ($node->taxonomy_terms as $term) {
-              if($term->name == $triplet['value']) {
-                $conditions_met = TRUE;
-                continue;
-              }
-            }
-        }
-      }
-      if ($conditions_met) {
-        $nodes[$nid] = $node;
-      }
-    }
-    else {
-      $nodes[$nid] = $node;
-    }
+      return array('channel_id', 'name', 'description', 'advertise', 'authtype', 'whenpub', 'username', 'pass', 'domains');
   }
-  return $nodes;
 }
 
 /**
@@ -1536,14 +1403,12 @@
  *   to this subscriber
  * @param $dest
  *   the URL of the XML-RPC endpoint to which content can be pushed
- * @param $cond
- *   an array of triplets describing how to filter content
  * @param $sid
  *   subscription id if not a new subscription
  *
  * @return $sid
  */
-function publish_subscription_save($channel_id, $username, $pass, $dest, $method, $remote_vids, $local_vids, $cond, $sid = null) {
+function publish_subscription_save($channel_id, $username, $pass, $dest, $method, $remote_vids, $local_vids, $sid = null) {
 
   $sub = NULL;
   $op = 'insert';
@@ -1591,89 +1456,48 @@
     }
   }
 
-  // save any additional conditions the subscriber requests
-  if ($cond) {
-    db_query("DELETE FROM {publish_cond} WHERE sid = %d", $sid);
-
-    list($clean_cond, $taxonomy_cond) = publish_cond_validate($cond);
-
-    foreach ($clean_cond as $triplet) {
-      $field = $triplet['field'];
-      $operator = $triplet['operator'];
-      $value = $triplet['value'];
-      db_query("INSERT INTO {publish_cond} (channel_id, sid, field, cond, value) VALUES %d, %d, '%s', '%s', '%s'", $channel_id, $sid, $field, $operator, $value);
-    }
-
-    foreach ($taxonomy_cond as $triplet) {
-      $field = $triplet['field'];
-      $operator = $triplet['operator'];
-      $value = $triplet['value'];
-      db_query("INSERT INTO {publish_cond} (channel_id, sid, field, cond, value) VALUES %d, %d, '%s', '%s', '%s'", $channel_id, $sid, $field, $operator, $value);
-    }
-  }
-
   return $sid;
 }
 
-function publish_supported_operators() {
-  return array (
-  '=',
-  '>',
-  '<'
-  );
-}
-
-function publish_supported_fields() {
-  return  array (
-  'nid',      'type',
-  'title',    'score',
-  'votes',    'uid',
-  'status',   'created',
-  'changed',  'comment',
-  'promote',  'moderate',
-  'users',    'teaser',
-  'body',     'sticky',
-  'format'
-  );
-}
+/********************************************************************
+ * Views Hooks
+ ********************************************************************/
 
 /**
- * We only support a limited number of fields and conditions.
- * This function filters out unsupported fields and conditions.
- *
- * @param $cond
- *   an array of triplets
- *
- * @return
- *   an array of triplets
+ * Provides a default view for views_multiblock
  */
-function publish_cond_validate($cond) {
-
-  $supported_operators = array_flip(publish_supported_operators());
-
-  $supported_fields = array_flip(publish_supported_fields());
-
-  $vocabularies = publish_get_vocabularies();
-  $voc_names = array();
-  foreach ($vocabularies as $v) {
-    $voc_names[$v->name] = 0;
-  }
-
-  $clean_cond = array();
-  foreach ($cond as $triplet) {
-    $field = isset($triplet['field']) ? $triplet['field'] : $triplet[0];
-    $operator = isset($triplet['operator']) ? $triplet['operator'] : $triplet[1];
-    $value = isset($triplet['value']) ? $triplet['value'] : $triplet[2];
-
-    // we need to treat node conditions and taxonomy conditions separately
-    // since node conditions are used for SQL building and taxonomy conditions are not
-    if (key_exists($operator, $supported_operators) && key_exists ($field, $supported_fields)) {
-      $clean_cond[] = array('field' => $field, 'operator' => $operator, 'value' => $value);
-    }
-    elseif (key_exists($field, $voc_names)) {
-      $taxonomy_cond[] = array('field' => $field, 'operator' => $operator, 'value' => $value);
-    }
-  }
-
-  return array($clean_cond, $taxonomy_cond);
-}
\ No newline at end of file
+function publish_views_default_views() {
+  $view = new stdClass();
+  $view->name = 'publish';
+  $view->description = 'A default channel view for the Publish module.';
+  $view->access = array (
+);
+  $view->view_args_php = '';
+  $view->sort = array (
+  );
+  $view->argument = array (
+    array (
+      'type' => 'taxid',
+      'argdefault' => '1',
+      'title' => '',
+      'options' => '',
+      'wildcard' => '',
+      'wildcard_substitution' => '',
+    ),
+  );
+  $view->field = array (
+    array (
+      'tablename' => 'node',
+      'field' => 'nid',
+      'label' => '',
+    ),
+  );
+  $view->filter = array (
+  );
+  $view->exposed_filter = array (
+  );
+  $view->requires = array(node);
+  $views[$view->name] = $view;
+  
+	return $views;
+}
diff -urN publish_47/publish_views.inc publish_5/publish_views.inc
--- publish_47/publish_views.inc	1969-12-31 19:00:00.000000000 -0500
+++ publish_5/publish_views.inc	2007-06-11 18:24:19.526581928 -0400
@@ -0,0 +1,330 @@
+<?php
+// $Id$
+
+/*********************************************************************
+ * Views Hooks
+ */
+
+/**
+ * Exposes certain Publish tables to views.
+ */
+function publish_views_tables() {
+  $tables['publish_queue'] = array(
+		'name' => 'publish_queue',
+		'join' => array(
+			'left' => array(
+				'table' => 'node',
+				'field' => 'nid',
+			),
+			'right' => array(
+				'field' => 'nid',
+			),
+		),
+		'fields' => array(
+			'qid' => array(
+				'name' => t('Publish: Queue ID'),
+				'help' => t('Use this field to show the Publish queue ID number.'),
+				'sortable' => TRUE,
+			),
+			'sid' => array(
+				'name' => t('Publish: Subscriber ID'),
+				'help' => t('Use this field to show the subscriber ID number.'),
+				'sortable' => TRUE,			
+			),
+			'channel_id' => array(
+				'name' => t('Publish: Channel ID'),
+				'help' => t('Use this field to show the channel ID number.'),
+				'sortable' => TRUE,
+			),
+			'attempts' => array(
+				'name' => t('Publish: Attempts'),
+				'help' => t('Use this field to show the number of attempts made to push a node.'),
+				'sortable' => TRUE,
+			),
+			'last_attempt' => array(
+				'name' => t('Publish: Last Attempt'),
+				'help' => t('Use this field to show the last time that Publish attempted to push a node.'),
+				'sortable' => TRUE,
+			),
+		),
+		'sorts' => array(
+			'qid' => array(
+				'name' => t('Publish: Queue ID'),
+				'help' => t('Sort by the Publish queue ID number.'),
+			),
+			'sid' => array(
+				'name' => t('Publish: Subscriber ID'),
+				'help' => t('Sort by the subscriber ID number.'),
+			),
+			'channel_id' => array(
+				'name' => t('Publish: Channel ID'),
+				'help' => t('Sort by the channel ID number.'),
+			),
+			'attempts' => array(
+				'name' => t('Publish: Attempts'),
+				'help' => t('Sort by the number of attempts made to push a node.'),
+			),
+			'last_attempt' => array(
+				'name' => t('Publish: Last Attempt'),
+				'help' => t('Sort by the last time that Publish attempted to push a node.'),
+			),
+		),
+		'filters' => array(
+			'channel_id' => array(
+				'field' => 'channel_id',
+				'name' => t('Publish: Channel ID'),
+				'operator' => 'views_handler_operator_or',
+				'list' => 'publish_views_get_channel_id_values',
+				'help' => t('Filter by the channel ID number.'),
+			),
+		),
+  );
+
+  $tables['publish_channel'] = array(
+		'name' => 'publish_channel',
+		'join' => array(
+			'left' => array(
+				'table' => 'publish_queue',
+				'field' => 'channel_id',
+			),
+			'right' => array(
+				'field' => 'channel_id',
+			),
+		),
+		'fields' => array(
+			'name' => array(
+				'name' => t('Publish: Channel Name'),
+				'help' => t('Use this field to show the Publish Channel name.'),
+				'sortable' => TRUE,
+			),
+			'description' => array(
+				'name' => t('Publish: Channel Description'),
+				'help' => t('Use this field to show the Publish Channel description.'),
+				'sortable' => TRUE,
+			),
+			'advertise' => array(
+				'name' => t('Publish: Channel is Advertised'),
+				'help' => t('Use this field to show whether or not the Publish Channel is advertised.'),
+				'sortable' => TRUE,
+			),
+		),
+		'sorts' => array(
+			'name' => array(
+				'name' => t('Publish: Channel Name'),
+				'help' => t('Sort by the Publish channel name.'),
+			),
+			'description' => array(
+				'name' => t('Publish: Channel Description'),
+				'help' => t('Sort by the Publish channel description.'),
+			),
+			'advertise' => array(
+				'name' => t('Publish: Channel is Advertised'),
+				'help' => t('Sort by the Publish channel advertised status.'),
+			),
+		),
+		'filters' => array(
+			'advertise' => array(
+				'field' => 'advertise',
+				'name' => t('Publish: Advertised'),
+				'operator' => 'views_handler_operator_or',
+				'list' => array(
+					t('Advertised'),
+					t('Not advertised'),
+				),
+				'help' => t('Filter by the Publish channel advertised status.'),
+			),
+		),
+	);
+
+  return $tables;
+}
+
+/**
+ * Provides a default view for publish
+ *
+function publish_views_default_views() {
+  $view = new stdClass();
+  $view->name = 'publish';
+
+  $view->description = 'Publish';
+  $view->access = array ('anonymous user');
+  $view->view_args_php = '';
+  $view->page = TRUE;
+  $view->page_title = '';
+  $view->page_header = '';
+  $view->page_header_format = '1';
+  $view->page_footer = '';
+  $view->page_footer_format = '1';
+  $view->page_empty = '';
+  $view->page_empty_format = '1';
+  $view->page_type = 'teaser';
+  $view->url = 'publish_view';
+  $view->use_pager = TRUE;
+  $view->nodes_per_page = '10';
+  $view->block = TRUE;
+  $view->block_title = '';
+  $view->block_header = '';
+  $view->block_header_format = '1';
+  $view->block_footer = '';
+  $view->block_footer_format = '1';
+  $view->block_empty = '';
+  $view->block_empty_format = '1';
+  $view->block_type = 'publish';
+  $view->nodes_per_block = '1';
+  $view->block_more = TRUE;
+  $view->block_use_page_header = FALSE;
+  $view->block_use_page_footer = FALSE;
+  $view->block_use_page_empty = FALSE;
+  $view->sort = array (
+    array (
+      'tablename' => 'node',
+      'field' => 'sticky',
+      'sortorder' => 'ASC',
+      'options' => '',
+    ),
+    array (
+      'tablename' => 'node',
+      'field' => 'changed',
+      'sortorder' => 'DESC',
+      'options' => 'normal',
+    ),
+    array (
+      'tablename' => 'node',
+      'field' => 'title',
+      'sortorder' => 'ASC',
+      'options' => '',
+    ),
+  );
+  $view->argument = array (
+    array (
+      'type' => 'taxid',
+      'argdefault' => '7',
+      'title' => '%1',
+      'options' => '',
+      'wildcard' => '',
+      'wildcard_substitution' => '',
+    ),
+    array (
+      'type' => 'node_feed',
+      'argdefault' => '2',
+      'title' => '',
+      'options' => 'News Feed',
+      'wildcard' => '',
+      'wildcard_substitution' => '',
+    ),
+  );
+  $view->field = array (
+    array (
+      'tablename' => 'node',
+      'field' => 'title',
+      'label' => '',
+      'handler' => 'views_handler_field_nodelink',
+      'options' => 'link',
+    ),
+    array (
+      'tablename' => 'node',
+      'field' => 'changed',
+      'label' => '',
+      'handler' => 'views_handler_field_date_small',
+    ),
+    array (
+      'tablename' => 'node',
+      'field' => 'body',
+      'label' => '',
+      'handler' => 'views_handler_field_teaser',
+    ),
+
+  );
+  $view->filter = array (
+    array (
+      'tablename' => 'node',
+      'field' => 'status',
+      'operator' => '=',
+      'options' => '',
+      'value' => '1',
+    ),
+  );
+  
+  $view->exposed_filter = array ();
+
+  $view->requires = array(node);
+  $views[$view->name] = $view;
+
+  return $views;  
+}
+*/
+
+/**
+ * Define additional view type names.
+ */
+function publish_info() {
+  return array(
+    'publish' => array('label' => 'Publish: Prepare for Channel'),
+  );
+}
+
+/**
+ *  Implementation of hook_views_style_plugins()
+ */
+function publish_views_style_plugins() {
+  
+  $plugins = array();
+  $types = publish_view_types();
+  foreach ($types as $name => $type) {
+    $plugins[$name] = array(
+      'name' => $type,
+      'theme' => 'publish_display',
+      'validate' => 'views_ui_plugin_validate_table',
+      'needs_fields' => TRUE,
+      'needs_table_header' => FALSE,
+      );
+  }
+  
+  return $plugins;
+}
+
+/**
+ *  Possible views page display types
+ */
+function publish_view_types() {
+  return array('publish' => t('Publish: Prepare for Channel'));
+}
+
+/**
+ *  A form element for a view selector
+ */
+function _publish_view_type_form($view = NULL) {
+  $form['publish_view'] = array(
+    '#type' => 'select',
+    '#options' => publish_view_types(),
+    '#default_value' => $view ? $view->page_type : 'publish',
+    '#title' => t('View'),
+    );
+  return $form;
+}
+
+/***********************************************************
+ * THEME FUNCTIONS 
+ */
+
+/**
+ *  Publish: XML plugin theme, overrides default views theme
+ */
+function theme_publish_display($view, $nodes) {
+	drupal_set_message(t('This view is for the Publish module, only.'), 'error');
+	return;
+}
+/*********************************************************************
+ * Helper Functions
+ */
+
+function publish_views_get_channel_id_values() {
+	$qs = db_query("SELECT pc.channel_id, pc.name FROM {publish_channel} pc");
+	while($obj = db_fetch_object($qs)) {
+		$filters[$obj->channel_id] = $obj->name;
+	}
+
+	return $filters;
+}
+
+?>
\ No newline at end of file
