Index: nodequeue.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/nodequeue/nodequeue.install,v
retrieving revision 1.22
diff -u -p -r1.22 nodequeue.install
--- nodequeue.install	13 Sep 2010 03:38:41 -0000	1.22
+++ nodequeue.install	30 Nov 2010 23:14:09 -0000
@@ -11,6 +11,11 @@ function nodequeue_schema() {
         'unsigned' => TRUE,
         'not null' => TRUE
       ),
+      'name' => array(
+        'description' => t('The machine name for the queue'),
+        'type' => 'varchar',
+        'length' => 32,
+      ),
       'title' => array(
         'description' => t('Title of a queue.'),
         'type' => 'varchar',
@@ -80,6 +85,9 @@ function nodequeue_schema() {
       ),
     ), // fields
     'primary key' => array('qid'),
+    'unique keys' => array(
+      'name' => array('name')
+    ),
   ); // nodequeue_queue.
   $schema['nodequeue_roles'] = array(
     'description' => t('Defines the roles which are allowed to use a particular nodequeue.'),
@@ -126,7 +134,7 @@ function nodequeue_schema() {
       'type' => array('type'),
     ), // indexes
   ); // nodequeue_types
-  
+
   // Subqueues are minor queues that inherit all of the properties of
   // the parent queue. A parent queue must have at least 1 subqueue
   // to do anything. Reference is for the use of whatever is creating
@@ -146,6 +154,11 @@ function nodequeue_schema() {
         'unsigned' => TRUE,
         'not null' => TRUE,
       ),
+      'name' => array(
+        'description' => t('The machine name of the subqueue.'),
+        'type' => 'varchar',
+        'length' => 32,
+      ),
       'reference' => array(
         'description' => '',
         'type' => 'varchar',
@@ -162,6 +175,9 @@ function nodequeue_schema() {
       ),
     ), // fields
     'primary key' => array('sqid'),
+    'unique keys' => array(
+      'name' => array('name')
+    ),
     'indexes' => array(
       'qid' => array('qid'),
       'reference' => array('reference'),
@@ -210,7 +226,7 @@ function nodequeue_schema() {
       'qid_nid' => array('qid', 'nid'),
     ), // indexes
   ); // nodequeue_nodes
-  
+
   return $schema;
 }
 
@@ -280,7 +296,7 @@ function nodequeue_update_5201() {
 
   // Create the nodequeue_subqueue table.
   $ret[] = update_sql("UPDATE {nodequeue_queue} SET owner = 'nodequeue', show_in_ui = 1, show_in_tab = 1, show_in_links = 1, reference = 0");
-  
+
   db_create_table($ret, 'nodequeue_subqueue', array(
     'description' => t('Subqueues are minor queues that inherit all of the properties of the parent queue. A parent queue must have at least 1 subqueue to do anything. Reference is for the use of whatever is creating the subqueues in order to link it to some other ID easily.'),
     'fields' => array(
@@ -474,6 +490,45 @@ function nodequeue_update_6006() {
   }
 }
 
+/*
+ * Provide machine names, and auto-generation of machine names for existing
+ * queues/subqueues.
+ */
+function nodequeue_update_6007() {
+  $ret = array();
+  db_add_field($ret, 'nodequeue_queue', 'name', array(
+    'type' => 'varchar',
+    'length' => 32,
+  ));
+  db_add_unique_key($ret, 'nodequeue_queue', 'name', array('name'));
+
+  db_add_field($ret, 'nodequeue_subqueue', 'name', array(
+    'type' => 'varchar',
+    'length' => 32,
+  ));
+  db_add_unique_key($ret, 'nodequeue_subqueue', 'name', array('name'));
+
+  // Auto-generate machine names for existing queues and subqueues. Existing
+  // queues will be named "queue{$qid}" while subqueues will be named
+  // "queue{$qid}_subqueue{$sqid}"
+  global $db_type;
+
+  if ($db_type == 'mysql' || $db_type == 'mysqli') {
+    $queue_update_sql = "UPDATE {nodequeue_queue} SET name = CONCAT('queue', qid)";
+    $subqueue_update_sql = "UPDATE {nodequeue_subqueue} SET name = CONCAT('queue', qid, '_subqueue', sqid)";
+  }
+  else {
+    $queue_update_sql = "UPDATE {nodequeue_queue} SET name = 'queue'||qid";
+    $subqueue_update_sql = "UPDATE {nodequeue_subqueue} SET name = 'queue'||qid||'_subqueue'||sqid";
+  }
+
+  $ret[] = update_sql($queue_update_sql);
+  $ret[] = update_sql($subqueue_update_sql);
+
+  return $ret;
+
+}
+
 function nodequeue_install() {
   drupal_install_schema('nodequeue');
 }
Index: nodequeue.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/nodequeue/nodequeue.module,v
retrieving revision 1.107
diff -u -p -r1.107 nodequeue.module
--- nodequeue.module	13 Sep 2010 03:32:47 -0000	1.107
+++ nodequeue.module	30 Nov 2010 23:14:10 -0000
@@ -714,6 +714,21 @@ function nodequeue_edit_queue_form(&$for
     '#description' => t('Enter the name of the queue'),
   );
 
+  $form['name'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Name'),
+    '#size' => 50,
+    '#maxlength' => 32,
+    '#description' => t("This is the unique name of the queue. It must contain only alphanumeric characters and underscores. It is used to identify the queue internally. This name cannot change. The machine name of the subqueue will be automatically generated using the queue's machine name and the subqueue title (if provided). If no title is provided for the subqueue, the subqueue's machine name will be numeric. (e.g. machinename_subqueue1)"),
+    '#required' => TRUE,
+  );
+
+  if (isset($queue->name)) {
+    $form['name']['#default_value'] = $queue->name;
+    $form['name']['#disabled'] = TRUE;
+    $form['name']['#value'] = $queue->name;
+  }
+
   // This is a value; as the default nodequeue implementation has just one
   // queue per nodequeue, this field is totally redundant. Plugins can
   // override this.
@@ -875,6 +890,12 @@ function nodequeue_edit_queue_form(&$for
  * Validate function for the nodequeue_queue form.
  */
 function nodequeue_edit_queue_form_validate($form, &$form_state) {
+  if (preg_match("/[^[:alnum:]_]/", $form_state['values']['name'])) {
+    form_set_error('name', t("The queue's machine name must consist of alphanumeric or underscore characters only."));
+  }
+  if (!nodequeue_machine_name_available($form_state['values']['name'], $form_state['values']['qid'])) {
+    form_set_error('name', t("The queue's machine name is already in use. Please choose a different machine name."));
+  }
   if (empty($form_state['values']['title'])) {
     form_set_error('title', t('Please enter a title for this queue.'));
   }
@@ -925,6 +946,27 @@ function nodequeue_edit_queue_form_submi
 }
 
 /**
+ * Determine if the machine name is in use.
+ */
+function nodequeue_machine_name_available($machine_name, $qid = NULL) {
+  // Find all existing records for the given machine_name
+  $result = db_query("SELECT qid FROM {nodequeue_queue} WHERE `name` LIKE '%s'", $machine_name);
+  $existing_queues = array();
+  while ($record = db_fetch_object($result)) {
+    $existing_queues[] = $record->qid;
+  }
+  if (count($existing_queues) == 0) {
+    // Creating a new machine name queue
+    return TRUE;
+  }
+  else if (count($existing_queues) == 1 && !empty($qid) && $qid == $existing_queues[0]) {
+    // Checking an existing queue that has not changed its name.
+    return TRUE;
+  }
+  return FALSE;
+}
+
+/**
  * Delete-validate function for the nodequeue_queue form.
  */
 function nodequeue_edit_queue_form_delete_validate($form, &$form_state) {
@@ -1480,6 +1522,20 @@ function nodequeue_load_queues_by_type($
   return nodequeue_load_queues(array_keys($qids), $bypass_cache);
 }
 
+
+/**
+ * Return a queue by its machine name. This is obviously not ideal due to the
+ * extra queries, but probably preferable to changing current API calls.
+ *
+ * @param $name
+ *   The queue's machine name
+ */
+function nodequeue_load_queue_by_name($name) {
+  $queue = db_fetch_object(db_query("SELECT qid FROM {nodequeue_queue} WHERE name = '%s'", $name) );
+  return isset($queue->qid) ? nodequeue_load_queues(array($queue->qid) ) : array();
+}
+
+
 /**
  * Used by menu system to determine access to the node and the queue in question.
  *
@@ -1782,6 +1838,20 @@ function nodequeue_load_subqueue($sqid, 
 
 }
 
+
+/**
+ * Return a subqueue by its machine name. This is obviously not ideal due to
+ * the extra queries, but probably preferable to changing current API calls.
+ *
+ * @param $name
+ *   The subqueue's machine name
+ */
+function nodequeue_load_subqueue_by_name($name) {
+  $subqueue = db_fetch_object(db_query("SELECT sqid FROM {nodequeue_subqueue} WHERE name = '%s'", $name) );
+  return isset($subqueue->sqid) ? nodequeue_load_subqueues(array($subqueue->sqid) ) : array();
+}
+
+
 /**
  * Load the entire set of subqueues for a queue.
  *
@@ -1885,14 +1955,20 @@ function nodequeue_load_subqueues_by_ref
  */
 function nodequeue_save(&$queue) {
   if (!isset($queue->qid)) {
-    db_query("INSERT INTO {nodequeue_queue} (title, subqueue_title, size, link, link_remove, owner, show_in_links, show_in_tab, show_in_ui, i18n, reverse, reference) VALUES ('%s', '%s', %d, '%s', '%s', '%s', %d, %d, %d, %d, %d, '%s')", $queue->title, $queue->subqueue_title, $queue->size, $queue->link, $queue->link_remove, $queue->owner, $queue->show_in_links, $queue->show_in_tab, $queue->show_in_ui, $queue->i18n, $queue->reverse, $queue->reference);
+    db_query("INSERT INTO {nodequeue_queue} (title, name, subqueue_title, size, link, link_remove, owner, show_in_links, show_in_tab, show_in_ui, i18n, reverse, reference) VALUES ('%s', '%s', '%s', %d, '%s', '%s', '%s', %d, %d, %d, %d, %d, '%s')", $queue->title, $queue->name, $queue->subqueue_title, $queue->size, $queue->link, $queue->link_remove, $queue->owner, $queue->show_in_links, $queue->show_in_tab, $queue->show_in_ui, $queue->i18n, $queue->reverse, $queue->reference);
     $queue->qid = db_last_insert_id('nodequeue_queue', 'qid');
     if (function_exists('views_invalidate_cache')) {
       views_invalidate_cache();
     }
   }
   else {
-    db_query("UPDATE {nodequeue_queue} set size = %d, title = '%s', subqueue_title = '%s', link = '%s', link_remove = '%s', owner = '%s', show_in_links = %d, show_in_tab = %d, show_in_ui = %d, i18n = %d, reverse = %d, reference = '%s' WHERE qid = %d", $queue->size, $queue->title, $queue->subqueue_title, $queue->link, $queue->link_remove, $queue->owner, $queue->show_in_links, $queue->show_in_tab, $queue->show_in_ui, $queue->i18n, $queue->reverse, $queue->reference, $queue->qid);
+    // Allow nodequeue to save and not update the name unless supplied
+    if (isset($queue->name) && !empty($queue->name)) {
+      db_query("UPDATE {nodequeue_queue} SET size = %d, title = '%s', subqueue_title = '%s', link = '%s', link_remove = '%s', owner = '%s', show_in_links = %d, show_in_tab = %d, show_in_ui = %d, i18n = %d, reverse = %d, reference = '%s' WHERE qid = %d", $queue->size, $queue->title, $queue->subqueue_title, $queue->link, $queue->link_remove, $queue->owner, $queue->show_in_links, $queue->show_in_tab, $queue->show_in_ui, $queue->i18n, $queue->reverse, $queue->reference, $queue->qid);
+    }
+    else {
+      db_query("UPDATE {nodequeue_queue} SET size = %d, title = '%s', name = '%s', subqueue_title = '%s', link = '%s', link_remove = '%s', owner = '%s', show_in_links = %d, show_in_tab = %d, show_in_ui = %d, i18n = %d, reverse = %d, reference = '%s' WHERE qid = %d", $queue->size, $queue->title, $queue->name, $queue->subqueue_title, $queue->link, $queue->link_remove, $queue->owner, $queue->show_in_links, $queue->show_in_tab, $queue->show_in_ui, $queue->i18n, $queue->reverse, $queue->reference, $queue->qid);
+    }
     db_query("DELETE FROM {nodequeue_roles} WHERE qid = %d", $queue->qid);
     db_query("DELETE FROM {nodequeue_types} WHERE qid = %d", $queue->qid);
   }
@@ -1943,13 +2019,13 @@ function nodequeue_delete($qid) {
 /**
  * Add a new subqueue to a queue.
  *
- * @param $qid
- *   The queue id. This should not be the full queue object.
+ * @param $queue
+ *   The queue object that this subqueue is being added to.
  * @param $reference
  *   A reference that uniquely identifies this subqueue. If NULL it will
  *   be assigned to the sqid.
  */
-function nodequeue_add_subqueue(&$queue, $title, $reference = NULL) {
+function nodequeue_add_subqueue(&$queue, $title, $reference = NULL, $name = NULL) {
   if (empty($reference)) {
     $insert_reference = "";
   }
@@ -1957,14 +2033,38 @@ function nodequeue_add_subqueue(&$queue,
     $insert_reference = $reference;
   }
 
-  $subqueue = new stdClass();;
+  $subqueue = new stdClass();
   $subqueue->reference = $reference;
   $subqueue->qid = $queue->qid;
   $subqueue->title = $title;
-
-  db_query("INSERT INTO {nodequeue_subqueue} (qid, reference, title) VALUES (%d, '%s', '%s')", $queue->qid, $insert_reference, $title);
+  
+  $count = 0;
+  if (!$name) {
+    if ($title) {
+      $stripped = preg_replace('/[^[:alnum:]]/', '', $title);
+      if (!empty($stripped)) {
+        // This means we do have some alpha-numeric characters in the title that 
+        // can be used to create the name.
+        $name = sprintf('%s_%s', $queue->name, preg_replace('/[^[:alnum:]_]/', '_', $title));
+      }
+    }
+    if (!$name) {
+      // If we still don't have a name we'll need to generate one based on a
+      // numeric representation of this subqueue.
+      $count = db_result(db_query("SELECT COUNT(sqid) FROM {nodequeue_subqueue} WHERE qid = %d", $queue->qid));
+      $name = sprintf('%s_%s', $queue->name, 'subqueue'. ++$count);
+    }
+  }
+  
+  // At this point we will have a valid name for our subqueue.
+  // If the name isn't unique our insert will fail and return false, in which case
+  // we'll add "_{count}" and keep trying until we get a unique name.
+  while (!@db_query("INSERT INTO {nodequeue_subqueue} (qid, reference, title, name) VALUES (%d, '%s', '%s', '%s')", $queue->qid, $insert_reference, $title, $name)) {
+    $name = sprintf('%s_%d', $name, $count++);
+  }
 
   $subqueue->sqid = db_last_insert_id('nodequeue_subqueue', 'sqid');
+  $subqueue->name = $name;
 
   // If somehow the $reference is null, here we set it to the sqid.
   // We have to do it here, because before the insert we don't know what the sqid will be.
@@ -2019,7 +2119,7 @@ function nodequeue_subqueue_add($queue, 
     }
     if (module_exists('apachesolr')) {
       apachesolr_mark_node($nid);
-    }  
+    }
     //Invoke the hook to notify other modules of the node addition.
     module_invoke_all('nodequeue_add', $subqueue->sqid, $nid);
   }
@@ -2073,7 +2173,7 @@ function nodequeue_subqueue_remove($sqid
   $diff = $end - $start + 1;
   db_query("DELETE FROM {nodequeue_nodes} WHERE sqid = %d AND position >= %d AND position <= %d", $sqid, $start, $end);
   db_query("UPDATE {nodequeue_nodes} SET position = position - %d WHERE sqid = %d AND position > %d",  $diff, $sqid, $end);
-  
+
   // Invoke the hook to let other modules know that the nodes were removed.
   while($node = db_fetch_object($result)) {
     module_invoke_all('nodequeue_remove', $sqid, $node->nid);
@@ -2553,7 +2653,7 @@ function nodequeue_api_autocomplete($que
     $where = '(n.status = 1 || n.uid = %d) AND ';
     $where_args = array($user->uid);
   }
-  
+
   $where .= "n.type IN (". db_placeholders($queue->types, 'varchar') .')';
   $where_args = array_merge($where_args, $queue->types);
 
Index: includes/views/nodequeue.views.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/nodequeue/includes/views/nodequeue.views.inc,v
retrieving revision 1.4
diff -u -p -r1.4 nodequeue.views.inc
--- includes/views/nodequeue.views.inc	23 Dec 2008 18:59:55 -0000	1.4
+++ includes/views/nodequeue.views.inc	30 Nov 2010 23:14:10 -0000
@@ -172,6 +172,24 @@ function nodequeue_views_data() {
     ),
   );
 
+  $data['nodequeue_queue']['name'] = array(
+    'title' => t('Queue machine name'),
+    'help' => t('The machine name of the queue.'),
+    'field' => array(
+      'handler' => 'views_handler_field',
+      'click sortable' => TRUE,
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_string',
+    ),
+    'argument' => array(
+      'handler' => 'views_handler_argument_string',
+    ),
+  );
+
   // ----------------------------------------------------------------
   // nodequeue_subqueue table
   $data['nodequeue_subqueue']['table']['group'] = t('Nodequeue');
@@ -202,6 +220,24 @@ function nodequeue_views_data() {
     ),
   );
 
+  $data['nodequeue_subqueue']['name'] = array(
+    'title' => t('Subqueue machine name'),
+    'help' => t('The machine name of the subqueue.'),
+    'field' => array(
+      'handler' => 'views_handler_field',
+      'click sortable' => TRUE,
+    ),
+    'sort' => array(
+      'handler' => 'views_handler_sort',
+    ),
+    'filter' => array(
+      'handler' => 'views_handler_filter_string',
+    ),
+    'argument' => array(
+      'handler' => 'views_handler_argument_string',
+    ),
+  );
+
   $data['nodequeue_subqueue']['reference'] = array(
     'title' => t('Subqueue reference'),
     'help' => t('The reference that defines a subqueue; what this actually is depends upon the type of subqueue, but is a taxonomy tid for smartqueue taxonomy, or a uid for authorview.'),
Index: includes/views/nodequeue.views_default.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/nodequeue/includes/views/nodequeue.views_default.inc,v
retrieving revision 1.5
diff -u -p -r1.5 nodequeue.views_default.inc
--- includes/views/nodequeue.views_default.inc	16 Mar 2010 22:07:26 -0000	1.5
+++ includes/views/nodequeue.views_default.inc	30 Nov 2010 23:14:10 -0000
@@ -16,7 +16,7 @@ function nodequeue_views_default_views()
   $queues = nodequeue_load_queues(nodequeue_get_all_qids(NULL));
   foreach ($queues as $queue) {
     $view = new view;
-    $view->name = "nodequeue_$queue->qid";
+    $view->name = "nodequeue_$queue->name";
     $view->description = t("Display a list of all nodes in queue '@queue'", array('@queue' => $queue->title));
     $view->tag = t('nodequeue');
     $view->view_php = '';
@@ -46,7 +46,7 @@ function nodequeue_views_default_views()
           'label' => 'queue',
           'required' => 1,
           'limit' => TRUE,
-          'qids' => array($queue->qid => $queue->qid),
+          'names' => array($queue->name => $queue->name),
           'relationship' => 'none',
         ),
       ),
Index: includes/views/nodequeue_handler_relationship_nodequeue.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/nodequeue/includes/views/nodequeue_handler_relationship_nodequeue.inc,v
retrieving revision 1.2
diff -u -p -r1.2 nodequeue_handler_relationship_nodequeue.inc
--- includes/views/nodequeue_handler_relationship_nodequeue.inc	31 Jan 2010 23:17:53 -0000	1.2
+++ includes/views/nodequeue_handler_relationship_nodequeue.inc	30 Nov 2010 23:14:10 -0000
@@ -4,11 +4,12 @@
  * Specialized relationship handler to add nodequeues.
  */
 class nodequeue_handler_relationship_nodequeue extends views_handler_relationship {
+
   function option_definition() {
     $options = parent::option_definition();
 
     $options['limit']['default'] = FALSE;
-    $options['qids']['default'] = array();
+    $options['names']['default'] = array();
     return $options;
   }
 
@@ -19,27 +20,38 @@ class nodequeue_handler_relationship_nod
   function options_form(&$form, &$form_state) {
     parent::options_form($form, $form_state);
 
-    $queues = nodequeue_load_queues(nodequeue_get_all_qids(NULL));
-
     $form['limit'] = array(
       '#type' => 'checkbox',
       '#title' => t('Limit to one or more queues (recommended)'),
       '#default_value'=> $this->options['limit'],
     );
 
-    $options = array();
+    $qids  = array();
+    $names = array();
     $queues = nodequeue_load_queues(nodequeue_get_all_qids(NULL));
     foreach ($queues as $queue) {
-      $options[$queue->qid] = $queue->title;
+      $qids[] = sprintf('%s:%s', $queue->name, $queue->qid);
+      $names[$queue->name] = $queue->title;
     }
 
+    // As the "nodequeue_nodes" table does not have the machine name field,
+    // executing the query (see function query() ) becomes difficult when
+    // this relationship is not required. The views_join object currently
+    // cannot handle complex joins (which would be required to handle this
+    // entirely in SQL). As a result, we'll store a qid -> machine name map
+    // in order to use local qids in the join query (in place of machine names).
     $form['qids'] = array(
-      '#prefix' => '<div><div id="edit-options-qids">',
+      '#type'  => 'hidden',
+      '#value' => implode(',', $qids),
+    );
+
+    $form['names'] = array(
+      '#prefix' => '<div><div id="edit-options-names">',
       '#suffix' => '</div></div>',
       '#type' => 'checkboxes',
       '#title' => t('Queues'),
-      '#options' => $options,
-      '#default_value' => $this->options['qids'],
+      '#options' => $names,
+      '#default_value' => $this->options['names'],
       '#process' => array('expand_checkboxes', 'views_process_dependency'),
       '#dependency' => array('edit-options-limit' => array(TRUE)),
     );
@@ -63,17 +75,23 @@ class nodequeue_handler_relationship_nod
     }
 
     if (!empty($this->options['limit'])) {
+      $qids = array();
+      $map  = explode(',', $this->options['qids']);
+      foreach($map as $value) {
+        list($name, $qid) = explode(':', $value);
+        if (isset($this->options['names'][$name]) ) {
+          $qids[] = $qid;
+        }
+      }
+
       $join->definition['extra'] = array(array(
         'field' => 'qid',
-        'value' => array_filter($this->options['qids']),
-        'numeric' => TRUE,
+        'value' => $qids,
       ));
     }
 
     $join->construct();
-
     $alias = $join->definition['table'] . '_' . $join->definition['left_table'];
-
     $this->alias = $this->query->add_relationship($alias, $join, 'nodequeue_nodes', $this->relationship);
   }
 }
\ No newline at end of file
