'admin/content/nodequeue', 'title' => t('Node queue'), 'access' => $access, 'callback' => 'nodequeue_admin_page', 'type' => MENU_NORMAL_ITEM ); $items[] = array( 'path' => 'admin/content/nodequeue/list', 'title' => t('List'), 'access' => $access, 'callback' => 'nodequeue_admin_page', 'weight' => -1, 'type' => MENU_DEFAULT_LOCAL_TASK ); $items[] = array( 'path' => 'admin/content/nodequeue/add', 'title' => t('Add'), 'access' => $access, 'callback' => 'drupal_get_form', 'callback arguments' => array('nodequeue_queue_form'), 'type' => MENU_LOCAL_TASK ); } else { if ($user && arg(0) == 'node' && is_numeric(arg(1)) && arg(1) > 0 && ($access = user_access('manipulate queues'))) { $node = node_load(arg(1)); if (nodequeue_node_access($node->type)) { $items[] = array( 'path' => 'node/' . arg(1) . '/nodequeue', 'title' => t('Node queue'), 'access' => $access, 'callback' => 'nodequeue_page', 'callback arguments' => array(arg(1)), 'type' => MENU_LOCAL_TASK, 'weight' => 5 ); } } if ($access = user_access('administer nodequeue') && arg(0) == 'admin' && arg(1) == 'content' && arg(2) == 'nodequeue' && is_numeric(arg(3)) && $queue = nodequeue_load(arg(3))) { drupal_set_title("Nodequeue '$queue->title'"); $items[] = array( 'path' => 'admin/content/nodequeue/' . arg(3), 'title' => t('View'), 'access' => $access, 'callback' => 'nodequeue_admin_view', 'callback arguments' => array($queue), 'type' => MENU_CALLBACK ); $items[] = array( 'path' => 'admin/content/nodequeue/' . arg(3) . '/view', 'title' => t('View'), 'access' => $access, 'callback' => 'nodequeue_admin_view', 'callback arguments' => array($queue), 'weight' => -10, 'type' => MENU_DEFAULT_LOCAL_TASK ); $items[] = array( 'path' => 'admin/content/nodequeue/' . arg(3) . '/edit', 'title' => t('Edit'), 'access' => $access, 'callback' => 'drupal_get_form', 'callback arguments' => array('nodequeue_queue_form', $queue), 'type' => MENU_LOCAL_TASK ); $items[] = array( 'path' => 'admin/content/nodequeue/' . arg(3) . '/delete', 'title' => t('Delete'), 'access' => $access, 'callback' => 'drupal_get_form', 'callback arguments' => array('nodequeue_admin_delete', $queue), 'weight' => 5, 'type' => MENU_CALLBACK ); $items[] = array( 'path' => 'admin/content/nodequeue/' . arg(3) . '/clear', 'title' => t('Clear'), 'access' => $access, 'callback' => 'drupal_get_form', 'callback arguments' => array('nodequeue_clear_confirm', $queue), 'type' => MENU_CALLBACK ); $items[] = array( 'path' => 'admin/content/nodequeue/' . arg(3) . '/oper', 'title' => t('Operate'), 'access' => $access, 'callback' => 'nodequeue_admin_operate', 'callback arguments' => array($queue), 'type' => MENU_CALLBACK ); } } return $items; } // -------------------------------------------------------------------------- // Nodequeue Admin pages /** * Display the queue page for a node, allowing the user to control * how the node exists in various queues. This controls a couple * of different paths. */ function nodequeue_page($nid, $op = NULL, $qid = NULL) { $node = node_load($nid); drupal_set_title(check_plain($node->title)); if (!nodequeue_node_access($node->type)) { return t('No node queue defined for this node type.'); } else { if ($op && $qid) { if ($op == 'add') { nodequeue_queue_add($qid, $nid); } elseif ($op == 'remove') { nodequeue_queue_remove_node($qid, $nid); } drupal_goto("node/$nid/nodequeue"); } return drupal_get_form('nodequeue_page_form', $node); } } /** * Display the queue controls for a node. */ function nodequeue_page_form($node) { // Determine which queues are appropriate for this nodetype. global $user; $roles_where = $roles_join = ''; $roles = array(); if (!user_access('manipulate all queues')) { $roles = array_keys((array) $user->roles) + array(DRUPAL_AUTHENTICATED_RID); $role_args = array_fill(0, count($roles), '%d'); $roles_join = "INNER JOIN {nodequeue_roles} nr ON nr.qid = nq.qid "; $roles_where = "AND nr.rid IN (". implode(',', $role_args) .") "; } // db_rewrite_sql should not be used here because the queue info needs // to always be correct here. $result = db_query( "SELECT nq.qid, nq.title, nq.size, MAX(nqn.position) AS num_nodes " . "FROM {nodequeue_queue} nq " . "INNER JOIN {nodequeue_types} nt ON nt.qid = nq.qid " . "LEFT JOIN {nodequeue_nodes} nqn ON nqn.qid = nq.qid " . $roles_join . "WHERE nt.type = '%s' " . $roles_where . "GROUP BY nq.qid ORDER BY nq.title", 'nq', 'qid', array_merge(array($node->type), $roles)); $form = array(); while ($queue = db_fetch_object($result)) { $form['title'][$queue->qid] = array('#type' => 'markup', '#value' => $queue->title); $form['size'][$queue->qid] = array('#type' => 'markup', '#value' => $queue->size); $form['num_nodes'][$queue->qid] = array('#type' => 'markup', '#value' => $queue->num_nodes . ($queue->size && $queue->size == $queue->num_nodes ? ' '. t('QUEUE FULL') : '')); $ops = array(l(t('View queue'), "admin/content/nodequeue/$queue->qid/view")); if (is_numeric($pos = db_result(db_query("SELECT position FROM {nodequeue_nodes} WHERE nid = %d AND qid = %d", $node->nid, $queue->qid)))) { $ops[] = l(t("Remove from queue"), "node/$node->nid/nodequeue/remove/$queue->qid/$pos"); } else { $ops[] = l(t("Add to queue"), "node/$node->nid/nodequeue/add/$queue->qid"); } $form['operations'][$queue->qid] = array('#type' => 'markup', '#value' => implode(' | ', $ops)); } return $form; } /** * Theme function for nodequeue_page_form */ function theme_nodequeue_page_form($form) { $header = array(t('Title'), t('Max nodes'), t('In queue'), t('Operation')); foreach (element_children($form['title']) as $key) { $row = array(); $row[] = drupal_render($form['title'][$key]); $row[] = array('data' => drupal_render($form['size'][$key]), 'align' => 'right'); $row[] = array('data' => drupal_render($form['num_nodes'][$key]), 'align' => 'right'); $row[] = drupal_render($form['operations'][$key]); $rows[] = $row; } $output .= theme('table', $header, $rows); $output .= drupal_render($form); return $output; } /** * Display a list of queues and their status for the administrator. */ function nodequeue_admin_page() { $result = pager_query('SELECT nq.*, COUNT(DISTINCT(nn.nid)) as nodes FROM {nodequeue_queue} nq LEFT JOIN {nodequeue_nodes} nn ON nq.qid = nn.qid GROUP by nq.title', 20, 0, 'SELECT COUNT(q.qid) FROM {nodequeue_queue} q'); if (db_num_rows($result)) { $header = array(t('Title'), t('Max Nodes'), t('In Queue'), t('Operation')); $rows = array(); while ($queue = db_fetch_object($result)) { $rows[] = array( $queue->title, array('data' => $queue->size), array('data' => $queue->nodes), array('data' => implode(' | ', array(l(t('Edit'), "admin/content/nodequeue/$queue->qid/edit"), l(t('View'), "admin/content/nodequeue/$queue->qid/view"), l(t('Delete'), "admin/content/nodequeue/$queue->qid/delete")))) ); } $output = theme('table', $header, $rows); $output .= theme('pager', NULL, 20); return $output; } else { return t('No node queues exist.'); } } /** * Add or edit a queue. */ function nodequeue_queue_form($queue = NULL) { if (!$queue) { $queue = new stdClass(); } $form['title'] = array( '#type' => 'textfield', '#title' => t('Title'), '#default_value' => $queue->title, '#size' => 50, '#maxlength' => 64, '#description' => t('Enter the name of the queue'), ); $form['size'] = array( '#type' => 'textfield', '#title' => t('Queue size'), '#default_value' => $queue->size, '#size' => 2, '#maxlength' => 2, '#description' => t('The maximum number of nodes will appear in the queue. Enter 0 for no limit'), ); $form['link'] = array( '#type' => 'textfield', '#title' => t('Link "add to queue" text'), '#default_value' => $queue->link, '#size' => 40, '#maxlength' => 40, '#description' => t('If you want a link to add a node to a queue in the "links" section (next to "add new comment"), enter the text here. If left blank no link will be given; note that enabling this feature for any queue will cause an extra query to be run every time a node is loaded.'), ); $form['link_remove'] = array( '#type' => 'textfield', '#title' => t('Link "remove from queue" text'), '#default_value' => $queue->link_remove, '#size' => 40, '#maxlength' => 40, '#description' => t('Enter the text for the corresponding link to remove a node from a queue. This may be blank (in which case no link will appear) but a remove link will only appear if link, above, is set.'), ); $result = db_query("SELECT * FROM {role} ORDER BY name"); while ($role = db_fetch_object($result)) { $roles[$role->rid] = $role->name; } $form['roles'] = array( '#type' => 'checkboxes', '#title' => t('Roles'), '#default_value' => $queue->roles, '#options' => $roles, '#description' => t('Check each role that can add nodes to the queue.'), ); foreach (node_get_types() as $type => $info) { $nodes[$type] = $info->name; } $form['types'] = array( '#type' => 'checkboxes', '#title' => t('Types'), '#default_value' => $queue->types, '#options' => $nodes, '#description' => t('Check each node type that can be added to this queue.'), ); $form[] = array( '#type' => 'submit', '#value' => t('Submit'), ); if ($queue->qid) { $form[] = array( '#type' => 'submit', '#value' => t('Delete'), ); $form['qid'] = array( '#type' => 'value', '#value' => $queue->qid, ); $form['count'] = array( '#type' => 'value', '#value' => $queue->count, ); } return $form; } /** * Submit function for the nodequeue_queue form. */ function nodequeue_queue_form_submit($formid, $form) { if ($_POST['op'] == t('Delete')) { return drupal_goto("admin/content/nodequeue/$form[qid]/delete"); } $queue = (object) $form; // fix checkboxes; sigh foreach ($queue->roles as $role => $value) { if ($value) { $roles[] = $role; } } $queue->roles = $roles; foreach ($queue->types as $type => $value) { if ($value) { $types[] = $type; } } $queue->types = $types; nodequeue_save($queue); if ($queue->size) // 0 means "don't care" _nodequeue_check_queuesize($queue); drupal_set_message(t('The queue has been updated.')); drupal_goto('admin/content/nodequeue'); } /** * Confirm form to delete a queue */ function nodequeue_admin_delete($queue) { $form['qid'] = array('#type' => 'value', '#value' => $queue->qid); return confirm_form($form, t('Are you sure you want to delete "%title"?', array('%title' => $queue->title)), $_GET['destination'] ? $_GET['destination'] : 'admin/content/nodequeue', t('This action cannot be undone.'), t('Delete'), t('Cancel') ); } /** * Submit function for nodequeue delete */ function nodequeue_admin_delete_submit($formid, $form) { if ($form['confirm']) { nodequeue_delete($form['qid']); drupal_set_message("The queue has been deleted."); } return 'admin/content/nodequeue'; } /** * Page callback to operate on a queue, moving items up or down if * javascript is disabled. */ function nodequeue_admin_operate($queue, $op = NULL, $pos = NULL) { switch ($op) { case 'up': nodequeue_queue_up($queue, $pos); break; case 'front': nodequeue_queue_front($queue, $pos); break; case 'down': nodequeue_queue_down($queue, $pos); break; case 'back': nodequeue_queue_back($queue, $pos); case 'remove': _nodequeue_queue_remove($queue, $pos); } return drupal_goto("admin/content/nodequeue/$qid/view"); } /** * Page callback to view a queue. */ function nodequeue_admin_view($queue) { $qid = $queue->qid; $output = ''; $output = '
'; $sql = "SELECT DISTINCT(n.nid), n.title, n.uid, u.name, n.created, nq.position FROM {node} n LEFT JOIN {users} u on n.uid = u.uid LEFT JOIN {nodequeue_nodes} nq ON nq.nid = n.nid WHERE nq.qid = $qid ORDER BY nq.position"; // Don't rewrite because a queue manager has to be able to move items up // and down in the queue even if they can't be viewed. // $sql = db_rewrite_sql($sql); $result = pager_query($sql, 25, 0); $list = array(); $nids = array(); if (db_num_rows($result) > 0) { while ($node = db_fetch_object($result)) { $buttons = l( theme('image', drupal_get_path('module', 'nodequeue') .'/go-up.png', t('Move up')), "admin/content/nodequeue/$qid/oper/up/$node->position", array( 'title' => t('Move up'), 'class' => 'nodequeue-move-up', ), NULL, NULL, FALSE, TRUE); $buttons .= l( theme('image', drupal_get_path('module', 'nodequeue') .'/go-down.png', t('Move down')), "admin/content/nodequeue/$qid/oper/down/$node->position", array( 'title' => t('Move down'), 'class' => 'nodequeue-move-down', ), NULL, NULL, FALSE, TRUE); $buttons .= l( theme('image', drupal_get_path('module', 'nodequeue') .'/go-top.png', t('Move to front')), "admin/content/nodequeue/$qid/oper/front/$node->position", array( 'title' => t('Move to front'), 'class' => 'nodequeue-move-front', ), NULL, NULL, FALSE, TRUE); $buttons .= l( theme('image', drupal_get_path('module', 'nodequeue') .'/go-bottom.png', t('Move to back')), "admin/content/nodequeue/$qid/oper/back/$node->position", array( 'title' => t('Move to back'), 'class' => 'nodequeue-move-back', ), NULL, NULL, FALSE, TRUE); $buttons .= l( theme('image', drupal_get_path('module', 'nodequeue') .'/user-trash.png', t('Remove from queue')), "admin/content/nodequeue/$qid/oper/remove/$node->position", array( 'title' => t('Remove from queue'), 'class' => 'nodequeue-remove', ), NULL, NULL, FALSE, TRUE); $list[] = array( 'id' => 'nodequeue-row-' . $node->nid, 'class' => 'nodequeue-row', 'data' => array(l($node->title, "node/$node->nid"), theme('username', $node), format_date($node->created), $buttons), ); $nids[] = $node->nid; } $header = array(t('Node'), t('Author'), t('Date'), t('Operation')); $output .= theme('table', $header, $list, array('width' => '100%', 'id' => 'nodequeue-table')); $output .= drupal_get_form('nodequeue_queue_admin', $qid, $nids); drupal_add_js(drupal_get_path('module', 'nodequeue') .'/nodequeue.js'); } else { $output .= t('Queue is empty!
'); } return $output; } /** * Form used for administrating a queue */ function nodequeue_queue_admin($qid, $nids) { $form['qid'] = array( '#type' => 'value', '#value' => $qid, ); $form['order'] = array( '#type' => 'hidden', '#id' => 'nodequeue-order', '#default_value' => implode(',', $nids), ); $form['save'] = array( '#type' => 'submit', '#attributes' => array('class' => 'nodequeue-js-hide nodequeue-save', 'style' => 'display: none'), '#value' => t('Save'), ); $form['clear'] = array( '#type' => 'submit', '#value' => t('Clear queue'), ); return $form; } /** * Submit function for nodequeue_queue_admin */ function nodequeue_queue_admin_submit($form_id, $form_values) { if ($form_values['op'] == t('Clear queue')) { return 'admin/content/nodequeue/' . $form_values['qid'] . '/clear'; } db_query("DELETE FROM {nodequeue_nodes} WHERE qid = %d", $form_values['qid']); if ($form_values['op'] == t('Save') && $form_values['order']) { $counter = 1; foreach (explode(',', $form_values['order']) as $nid) { db_query("INSERT INTO {nodequeue_nodes} (qid, nid, position) VALUES (%d, %d, %d)", $form_values['qid'], $nid, $counter++); } } drupal_set_message(t('The queue has been updated')); } /** * Confirm form to clear a queue. */ function nodequeue_clear_confirm($queue) { $form['qid'] = array('#type' => 'value', '#value' => $qid); return confirm_form($form, t('Clearing queue "%s" is irreversible. You sure?', array('%s' => $queue->title)), $_GET['destination'] ? $_GET['destination'] : "admin/content/nodequeue/$queue->qid/view", t('This action cannot be undone.'), t('Clear Queue'), t('Cancel') ); } /** * Submit function for nodequeue clear confirm */ function nodequeue_clear_confirm_submit($formid, $form) { if ($form['confirm']) { nodequeue_queue_clear($form['qid']); return drupal_goto("admin/content/nodequeue/$form[qid]/view"); } } /** * Implementation of hook_nodeapi */ function nodequeue_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) { switch($op) { case 'delete': // If a node is being deleted, ensure it's also removed from any queues. $result = db_query("SELECT * FROM {nodequeue_nodes} WHERE nid = %d", $node->nid); while ($obj = db_fetch_object($result)) { nodequeue_queue_remove($obj->qid, $obj->position); } break; } } /** * Implementation of hook_link */ function nodequeue_link($type, $node, $teaser) { if ($type == 'node' && variable_get('nodequeue_links', FALSE) && user_access('manipulate queues')) { $roles_join = $roles_where = ''; $roles = array(); if (!user_access('manipulate all queues')) { $roles_join = "INNER JOIN {nodequeue_roles} nr ON nr.qid = nq.qid "; $roles = array_keys((array) $user->roles) + array(DRUPAL_AUTHENTICATED_RID); $role_args = array_fill(0, count($roles), '%d'); $roles_where .= "AND nr.rid IN (". implode(',', $role_args) .")"; } $sql = 'SELECT nq.qid, nq.link, nq.link_remove, nqn.position FROM {nodequeue_queue} nq ' . 'INNER JOIN {nodequeue_types} nt ON nt.qid = nq.qid ' . $roles_join . 'LEFT JOIN {nodequeue_nodes} nqn ON nqn.qid = nq.qid AND nqn.nid = %d ' . "WHERE nt.type = '%s' " . $roles_where; $result = db_query($sql, array_merge(array($node->nid, $node->type), $roles)); $links = array(); while ($queue = db_fetch_object($result)) { if (!$queue->position) { $links[] = array( 'title' => $queue->link, 'href' => "node/$node->nid/nodequeue/add/$queue->qid", 'query' => drupal_get_destination()); } else if ($queue->link_remove) { $links[] = array( 'title' => $queue->link_remove, 'href' => "node/$node->nid/nodequeue/remove/$queue->qid", 'query' => drupal_get_destination()); } } } return $links; } // -------------------------------------------------------------------------- // Database manipulation functions /** * Return TRUE if $user can * control the queue for this node. */ function nodequeue_node_access($type) { global $user; $roles_join = $roles_where = ''; $roles = array(); // superuser always has access. if (!user_access('manipulate all queues')) { $roles_join = "INNER JOIN {nodequeue_roles} nr ON nr.qid = nq.qid "; $roles = array_keys((array) $user->roles) + array(DRUPAL_AUTHENTICATED_RID); $role_args = array_fill(0, count($roles), '%d'); $roles_where .= "AND nr.rid IN (". implode(',', $role_args) .")"; } $sql = 'SELECT nq.qid FROM {nodequeue_queue} nq ' . 'INNER JOIN {nodequeue_types} nt ON nt.qid = nq.qid ' . $roles_join . "WHERE nt.type = '%s' " . $roles_where; $result = db_query($sql, array_merge(array($type), $roles)); return db_num_rows($result); } function _nodequeue_load($qid, $nodes = false) { // passthrough for compatibility return nodequeue_load($qid, $nodes); } function nodequeue_load($qid, $nodes = false) { $queue = db_fetch_object(db_query("SELECT * FROM {nodequeue_queue} WHERE qid = %d", $qid)); if ($queue) { $result = db_query("SELECT rid FROM {nodequeue_roles} WHERE qid = %d", $qid); while ($obj = db_fetch_object($result)) $queue->roles[] = $obj->rid; $result = db_query("SELECT type FROM {nodequeue_types} WHERE qid = %d", $qid); while ($obj = db_fetch_object($result)) $queue->types[] = $obj->type; $queue->count = db_result(db_query("SELECT count(*) from {nodequeue_nodes} where qid = %d", $qid)); if ($nodes) { $result = db_query("SELECT nid FROM {nodequeue_nodes} WHERE qid = $qid ORDER BY position"); while ($obj = db_fetch_object($result)) { $queue->nodes[] = $obj->nid; } } } return $queue; } function _nodequeue_save($queue, $nodes = false) { // passthrough for compatibility with older versions return nodequeue_save($queue, $nodes); } function nodequeue_save($queue, $nodes = false) { $queue->size = intval($queue->size); $title = db_escape_string($queue->title); if (!$queue->qid) { $queue->qid = db_next_id("{nodequeue_queue}_qid"); db_query("INSERT INTO {nodequeue_queue} (qid, title, size, link, link_remove) VALUES (%d, '%s', %d, '%s', '%s')", $queue->qid, $title, $queue->size, $queue->link, $queue->link_remove); if (module_exists('views_invalidate_cache')) { views_invalidate_cache(); } } else { $queue->qid = intval($queue->qid); db_query("UPDATE {nodequeue_queue} set size = %d, title = '%s', link = '%s', link_remove = '%s' WHERE qid = %d", $queue->size, $title, $queue->link, $queue->link_remove, $queue->qid); db_query("DELETE FROM {nodequeue_roles} WHERE qid = %d", $queue->qid); db_query("DELETE FROM {nodequeue_types} WHERE qid = %d", $queue->qid); if ($nodes) { db_query("DELETE FROM {nodequeue_nodes} WHERE qid = %d", $queue->qid); } } if (is_array($queue->roles)) { foreach($queue->roles as $rid) db_query("INSERT INTO {nodequeue_roles} (qid, rid) VALUES (%d, %d)", $queue->qid, $rid); } if (is_array($queue->types)) { foreach($queue->types as $type) db_query("INSERT INTO {nodequeue_types} (qid, type) VALUES (%d, '%s')", $queue->qid, $type); } if ($nodes && is_array($queue->nodes)) { foreach($queue->nodes as $nid) { db_query("INSERT INTO {nodequeue_roles} (qid, nid, position) VALUES (%d, %d, %d)", $queue->qid, $nid, ++$position); // Stop if we somehow have more nodes in the queue than are allowed. if ($position >= $queue->size) break; } } // set our global that tells us whether or not we need to activate hook_link if (db_result(db_query("SELECT COUNT(*) FROM {nodequeue_queue} WHERE link != ''"))) { variable_set('nodequeue_links', TRUE); } else { variable_set('nodequeue_links', FALSE); } return $queue->qid; } function _nodequeue_delete($qid) { // passthrough return nodequeue_delete($qid); } function nodequeue_delete($qid) { db_query("DELETE FROM {nodequeue_queue} WHERE qid = %d", $qid); db_query("DELETE FROM {nodequeue_roles} WHERE qid = %d", $qid); db_query("DELETE FROM {nodequeue_types} WHERE qid = %d", $qid); db_query("DELETE FROM {nodequeue_nodes} WHERE qid = %d", $qid); } // -------------------------------------------------------------------------- // Queue position control function nodequeue_queue_swap($queue, $pos1, $pos2) { // Grab the nid off one of the positions so we can more easily swap. $nid = db_result(db_query("SELECT nid FROM {nodequeue_nodes} WHERE qid = %d AND position = %d", $queue->qid, $pos1)); if (!$nid) { return; } db_query("UPDATE {nodequeue_nodes} SET position = %d WHERE position = %d AND qid = %d", $pos1, $pos2, $queue->qid); db_query("UPDATE {nodequeue_nodes} SET position = %d WHERE nid = %d AND qid = %d", $pos2, $nid, $queue->qid); } function nodequeue_queue_up($queue, $position) { if ($position < 2 || $position > $queue->count) return; nodequeue_queue_swap($queue, $position - 1, $position); } function nodequeue_queue_down($queue, $position) { if ($position < 1 || $position >= $queue->count) return; nodequeue_queue_swap($queue, $position + 1, $position); } function nodequeue_queue_front($queue, $position) { if ($position < 2 || $position > $queue->count) return; $entry = db_fetch_object(db_query("SELECT * FROM {nodequeue_nodes} WHERE qid= %d AND position = %d", $queue->qid, $position)); db_query("DELETE FROM {nodequeue_nodes} WHERE qid = %d AND position = %d", $queue->qid, $position); db_query("UPDATE {nodequeue_nodes} SET position = position + 1 WHERE qid= %d AND position < %d", $queue->qid, $position); db_query("INSERT INTO {nodequeue_nodes} (qid, nid, position) VALUES (%d, %d, 1)", $queue->qid, $entry->nid); } function nodequeue_queue_back($queue, $position) { if ($position < 1 || $position >= $queue->count) return; $entry = db_fetch_object(db_query("SELECT * FROM {nodequeue_nodes} WHERE qid = %d AND position = %d", $queue->qid, $position)); db_query("DELETE FROM {nodequeue_nodes} WHERE qid = %d AND position = %d", $queue->qid, $position); db_query("UPDATE {nodequeue_nodes} SET position = position - 1 WHERE qid = %d AND position > %d", $queue->qid, $position); db_query("INSERT INTO {nodequeue_nodes} (qid, nid, position) VALUES (%d, %d, %d)", $queue->qid, $entry->nid, $queue->count); } function _nodequeue_queue_remove(&$queue, $start, $end = 0) { if (!$end) $end = $start; $diff = $end - $start + 1; db_query("DELETE FROM {nodequeue_nodes} WHERE qid = %d AND position >= %d AND position <= %d", $queue->qid, $start, $end); db_query("UPDATE {nodequeue_nodes} SET position = position - %d WHERE qid = %d AND position > %d", $diff, $queue->qid, $end); $queue->count -= $diff; } function _nodequeue_queue_add(&$queue, $nid) { // Check for uniqueness if (db_result(db_query("SELECT nid from {nodequeue_nodes} WHERE qid = %d AND nid = %d", $queue->qid, $nid))) { return; } // Really, it should never happen that a queue gets bigger than is possible, // but just in case. if ($queue->size) // 0 means infinity so never do this if false _nodequeue_check_queuesize($queue, $queue->size - 1); $nid = intval($nid); $queue->count++; db_query("INSERT INTO {nodequeue_nodes} (qid, nid, position) VALUES (%d, %d, %d)", $queue->qid, $nid, $queue->count); } function nodequeue_queue_clear($qid) { db_query("DELETE FROM {nodequeue_nodes} WHERE qid = %d", $qid); } function _nodequeue_check_queuesize(&$queue, $size = FALSE) { if ($size === FALSE) $size = $queue->size; if ($queue->count > $size) { _nodequeue_queue_remove($queue, 1, $queue->count - $size); } } /** * Get the position of a node in a queue, or 0 if not found. */ function nodequeue_queue_position($qid, $nid) { return db_result(db_query("SELECT position FROM {nodequeue_nodes} WHERE qid = %d AND nid = %d", $qid, $nid)); } // -------------------------------------------------------------------------- // Actions module function action_nodequeue_add($op, $edit = array(), $node) { switch($op) { case 'metadata': return array( 'description' => t('Add to Node Queue'), 'type' => t('node'), 'batchable' => true, 'configurable' => true, ); break; case 'do': $qid = $edit['qid']; nodequeue_queue_add($qid, $node->nid); break; // return an HTML config form for the action case 'form': // default values for form if (!isset($edit['qid'])) $edit['qid'] = ''; $result = db_query("SELECT * from {nodequeue_queue} ORDER BY title"); while ($obj = db_fetch_object($result)) $queues[$obj->qid] = $obj->title; // add form components $form['qid'] = array( '#type' => 'select', '#title' => t("Queue"), '#default_value' => $edit['qid'], '#options' => $queues, ); return $form; // validate the HTML form // process the HTML form to store configuration case 'submit': $params = array( 'qid' => $edit['qid'] ); return $params; break; } } function action_nodequeue_remove($op, $edit = array(), $node) { switch($op) { case 'metadata': return array( 'description' => t('Remove from Node Queue'), 'type' => t('node'), 'batchable' => true, 'configurable' => true, ); break; case 'do': $qid = $edit['qid']; nodequeue_queue_remove_node($qid, $node->nid); break; // return an HTML config form for the action case 'form': // default values for form if (!isset($edit['qid'])) $edit['qid'] = ''; $result = db_query("SELECT * from {nodequeue_queue} ORDER BY title"); while ($obj = db_fetch_object($result)) $queues[$obj->qid] = $obj->title; // add form components $form['qid'] = array( '#type' => 'select', '#title' => t("Queue"), '#default_value' => $edit['qid'], '#options' => $queues, ); return $form; break; // validate the HTML form // process the HTML form to store configuration case 'submit': $params = array( 'qid' => $edit['qid'] ); return $params; break; } } // -------------------------------------------------------------------------- // External queue fetching /** * in general it's preferable to use Views for this functionality. */ function nodequeue_node_titles($qid, $title = '', $backward = true, $from = 0, $count = 0) { $orderby = ($backward ? "DESC" : "ASC"); $sql = db_rewrite_sql("SELECT n.nid, n.title FROM {node} n LEFT JOIN {nodequeue_nodes} nn ON n.nid = nn.nid WHERE nn.qid = %d AND n.status = 1 ORDER BY nn.position $orderby"); if ($count) { $result = db_query_range($sql, $qid, $from, $count); } else { $result = db_query($sql, $qid); } return node_title_list($result, $title); } function nodequeue_nodes($qid, $backward = true, $teaser = true, $links = true, $from = 0, $count = 0) { $orderby = ($backward ? "DESC" : "ASC"); $sql = db_rewrite_sql("SELECT n.nid FROM {node} n INNER JOIN {nodequeue_nodes} nn ON n.nid = nn.nid WHERE nn.qid = %d AND n.status = 1 ORDER BY nn.position $orderby"); if ($count) { $result = db_query_range($sql, $qid, $from, $count); } else { $result = db_query($sql, $qid); } while ($nid = db_fetch_object($result)) { $node = node_load($nid->nid); $output .= node_view($node, $teaser, false, $links); } return $output; } function nodequeue_fetch_front($qid, $teaser = true, $links = true) { return nodequeue_nodes($qid, false, $teaser, $links, 0, 1); } function nodequeue_fetch_back($qid, $teaser = true, $links = true) { return nodequeue_nodes($qid, true, $teaser, $links, 0, 1); } function nodequeue_fetch_random($qid, $teaser = true, $links = true) { $count = db_result(db_query("SELECT count(*) FROM {nodequeue_nodes} WHERE qid = %d", $qid)); return nodequeue_nodes($qid, false, $teaser, $links, rand(0, $count - 1), 1); } function nodequeue_queue_add($qid, $nid) { $queue = _nodequeue_load($qid); if ($queue) { _nodequeue_queue_add($queue, $nid); } } function nodequeue_queue_remove($qid, $start, $end = 0) { $queue = _nodequeue_load($qid); if ($queue) { _nodequeue_queue_remove($queue, $start, $end); } } function nodequeue_queue_remove_node($qid, $nid) { if ($pos = nodequeue_queue_position($qid, $nid)) { nodequeue_queue_remove($qid, $pos); } } // --------------------------------------------------------------------------- // Views support function nodequeue_views_tables() { $tables['nodequeue_nodes'] = array( "name" => "nodequeue_nodes", "join" => array( "left" => array( "table" => "node", "field" => "nid" ), "right" => array( "field" => "nid" ), ), "filters" => array( "qid" => array( 'name' => "NodeQueue: Queue", 'list' => 'nodequeue_handler_queuelist', 'operator' => 'views_handler_operator_andor', 'help' => t('Filter the view to a specific Node Queue.'), ), "position" => array( 'name' => "NodeQueue: Queue Position", 'field' => 'position', 'operator' => 'views_handler_operator_gtlt', 'help' => t('Filter by where in the queue an item is.'), ), ), "sorts" => array( "position" => array( 'name' => "NodeQueue: Queue Position", 'field' => 'position', 'help' => t('When sorting by queue position, be sure the view is filtered to a single queue or the sort will not work very well.'), ), ), ); $tables['nodequeue_queue'] = array( "name" => "nodequeue_queue", "join" => array( "left" => array( "table" => "nodequeue_nodes", "field" => "qid" ), "right" => array( "field" => "qid" ), ), ); return $tables; } function nodequeue_views_arguments() { $arguments = array( 'nodequeue_qid' => array( 'name' => t("NodeQueue: Queue ID"), 'handler' => "nodequeue_handler_arg_qid", 'help' => t('The Queue ID argument allows users to filter a view by specifying a Node Queue ID.'), ), ); return $arguments; } function nodequeue_views_default_views() { $result = db_query("SELECT * FROM {nodequeue_queue}"); while ($queue = db_fetch_object($result)) { $view = new stdClass(); $view->name = "nodequeue_$queue->qid"; $view->disabled = TRUE; $view->description = t('View node queue ') . check_plain($queue->title); $view->access = array(); $view->view_args_php = ''; $view->page = TRUE; $view->page_title = check_plain($queue->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 = 'nodequeue/' . $queue->qid; $view->use_pager = TRUE; $view->nodes_per_page = '10'; $view->block = TRUE; $view->block_title = check_plain($queue->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 = 'list'; $view->nodes_per_block = '5'; $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' => 'nodequeue_nodes', 'field' => 'position', 'sortorder' => 'ASC', 'options' => '', ), ); $view->argument = array ( ); $view->field = array ( array ( 'tablename' => 'node', 'field' => 'title', 'label' => '', 'handler' => 'views_handler_field_nodelink', 'options' => 'link', ), ); $view->filter = array ( array ( 'tablename' => 'nodequeue_nodes', 'field' => 'qid', 'operator' => 'OR', 'options' => '', 'value' => array($queue->qid), ), ); $view->exposed_filter = array ( ); $view->requires = array('nodequeue_nodes', 'node'); $views[$view->name] = $view; } return $views; } function nodequeue_handler_queuelist() { $result = db_query("SELECT * FROM {nodequeue_queue} ORDER BY title"); while ($queue = db_fetch_object($result)) { $items[$queue->qid] = $queue->title; } return $items; } function nodequeue_handler_arg_qid($op, &$query, $argtype, $arg = '') { switch($op) { case 'summary': $query->ensure_table('nodequeue_queue', true); $query->add_field('title', 'nodequeue_queue'); $query->add_field('qid', 'nodequeue_queue'); $query->add_where('nodequeue_queue.qid IS NOT NULL'); $fieldinfo['field'] = "nodequeue_queue.title"; return $fieldinfo; break; case 'sort': $query->add_orderby('nodequeue_queue', 'title', $argtype); break; case 'filter': $qid = intval($arg); $query->ensure_table('nodequeue_queue', true); $query->add_where("nodequeue_queue.qid = %d", $qid); break; case 'link': return l($query->title, "$arg/" . intval($query->qid)); case 'title': $queue = db_fetch_object(db_query("SELECT title FROM {nodequeue_queue} WHERE qid = %d", $query->qid)); return $queue->title; } }