'. t('Max nodes in queue: @size', array('@size' => $queue->size ? $queue->size : t('Infinite'))) .'

'; $output .= '

'. t('Use the list below to configure and review the nodes in this nodequeue.'); $output .= '

'; $output .= t('To change the position of a node, grab a drag-and-drop handle under the Title column and drag it to a new location in the queue. (Grab a handle by clicking and holding the mouse while hovering over a handle icon.) Remember that your changes will not be saved until you click the Save button at the bottom of the page.') .'

'; $output .= '

'; } return $output; } /** * Implementation of hook_menu(). */ function nodequeue_dragdrop_menu() { $items = array(); $items['nodequeue_dragdrop/%nodequeue/%subqueue'] = array( 'title' => t('View'), 'page callback' => 'nodequeue_dragdrop_admin_view', 'page arguments' => array(1, 2), 'access arguments' => array(1, 2), 'access callback' => 'nodequeue_queue_access', 'type' => MENU_CALLBACK, ); return $items; } /** * Implementation of hook_theme(). */ function nodequeue_dragdrop_theme() { return array( 'nodequeue_dragdrop_form' => array( 'arguments' => array('form'), ), ); } /** * Implementation of hook_elements(). */ function nodequeue_dragdrop_elements() { $type = array(); $type['position'] = array( '#input' => TRUE, '#delta' => 10, '#default_value' => 0, '#process' => array('process_position', 'form_expand_ahah'), ); return $type; } /* --- CALLBACKS ------------------------------------------------------------ */ /** * Page callback to view a queue. */ function nodequeue_dragdrop_admin_view($queue, $subqueue = NULL) { // set title and load subqueue if it's not provided drupal_set_title(t("Nodequeue '@title'", array('@title' => $queue->title))); if (!$subqueue->sqid) { if ($queue->subqueues == 1) { $subqueues = nodequeue_load_subqueues_by_queue($queue->qid); $subqueue = array_shift($subqueues); } else { return drupal_not_found(); } } else if ($subqueue->sqid) { if (!nodequeue_api_subqueue_access($subqueue, NULL, $queue)) { return drupal_not_found(); } drupal_set_title(t("Subqueue '@title'", array('@title' => nodequeue_title_substitute($queue->subqueue_title, $queue, $subqueue)))); } // get nodes from the queue $nodes = _nodequeue_dragdrop_get_nodes($queue, $subqueue); return drupal_get_form('nodequeue_dragdrop_form', $queue, $nodes, $subqueue); } /* --- FORMS ---------------------------------------------------------------- */ /** * Expand position elements into selects. Works like the weight element, except * only positive values are allowed. */ function process_position($element) { for ($n = 1; $n <= $element['#delta']; $n++) { $positions[$n] = $n; } $element['#options'] = $positions; $element['#type'] = 'select'; $element += _element_info('select'); return $element; } /** * If no default value is set for position select boxes, use 1. */ function position_value(&$form) { if (isset($form['#default_value'])) { $form['#value'] = $form['#default_value']; } else { $form['#value'] = 1; } } /** * Form definition for nodequeue drag'n'drop form. */ function nodequeue_dragdrop_form($form_state, $queue, $nodes, $subqueue) { $form = array('#tree' => TRUE); // save queue and subqueue objects for later use $form['#queue'] = (array) $queue; $form['#subqueue'] = (array) $subqueue; // prepare the main part of the form which will be themed as a table $count = count($nodes); foreach ($nodes as $node) { $form[$node->nid]['#node'] = (array) $node; $form[$node->nid]['title'] = array('#value' => l($node->title, 'node/' . $node->nid)); $form[$node->nid]['author'] = array('#value' => theme('username', $node)); $form[$node->nid]['date'] = array('#value' => format_date($node->created)); $form[$node->nid]['edit'] = array('#value' => l(t('edit'), 'node/' . $node->nid . '/edit')); $form[$node->nid]['remove'] = array('#value' => l(t('remove'), 'nodequeue_dragdrop/remove/' . $node->nid)); $form[$node->nid]['position'] = array( '#type' => 'position', '#delta' => $count, '#default_value' => $node->position, '#attributes' => array( 'class' => 'node-position', ), ); } // add submit, reverse, and shuffle buttons $form['submit'] = array( '#type' => 'submit', '#value' => t('Save') ); $form['reverse'] = array( '#type' => 'submit', '#value' => t('Reverse'), '#submit' => array('nodequeue_dragdrop_form_reverse_submit'), ); $form['shuffle'] = array( '#type' => 'submit', '#value' => t('Shuffle'), '#submit' => array('nodequeue_dragdrop_form_shuffle_submit'), ); return $form; } /** * Submit handler for nodequeue drag'n'drop form. Updates node positions in {nodequeue_nodes}. */ function nodequeue_dragdrop_form_submit($form, &$form_state, $reverse = FALSE, $shuffle = FALSE) { $nodes = array(); foreach ($form_state['values'] as $nid => $element) { if (is_numeric($nid)) { $nodes[$form_state['values'][$nid]['position']] = $nid; } } // reverse the list if the queue is set to display in reverse or if the // reverse button was clicked. ksort($nodes); if ($form['#queue']['reverse'] xor $reverse) { krsort($nodes); } // shuffle the list if the shuffle button was pressed. if ($shuffle) { $keys = array_keys($nodes); $values = array_values($nodes); shuffle($values); $nodes = array_combine($keys, $values); } $qid = $form['#queue']['qid']; $sqid = $form['#subqueue']['sqid']; $position = 1; foreach ($nodes as $nid) { db_query('UPDATE {nodequeue_nodes} SET position = %d WHERE qid = %d AND sqid = %d AND nid = %d', $position, $qid, $sqid, $nid); $position++; } } /** * Submit handler for nodequeue drag'n'drop reverse button. */ function nodequeue_dragdrop_form_reverse_submit($form, &$form_state) { nodequeue_dragdrop_form_submit($form, $form_state, TRUE); } /** * Submit handler for nodequeue drag'n'drop shuffle button. */ function nodequeue_dragdrop_form_shuffle_submit($form, &$form_state) { nodequeue_dragdrop_form_submit($form, $form_state, FALSE, TRUE); } /* --- UTILITY -------------------------------------------------------------- */ /** * Return a list of nodes in a specific subqueue. */ function _nodequeue_dragdrop_get_nodes($queue, $subqueue) { $order = $queue->reverse ? 'DESC' : 'ASC'; $result = db_query("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.sqid = %d ORDER BY nq.position $order", $subqueue->sqid); $nodes = array(); while ($node = db_fetch_object($result)) { $nodes[] = $node; } return $nodes; } /* --- THEME ---------------------------------------------------------------- */ /** * Theme the subqueue overview as a sortable list. */ function theme_nodequeue_dragdrop_form($form) { $output = ''; // get css to hide some of the help text if javascript is disabled drupal_add_css(drupal_get_path('module', 'nodequeue') . '/nodequeue.css'); drupal_add_tabledrag('nodequeue-dragdrop', 'order', 'sibling', 'node-position'); // render form as table rows $rows = array(); foreach (element_children($form) as $key) { if (isset($form[$key]['title'])) { $row = array(); $row[] = drupal_render($form[$key]['title']); $row[] = drupal_render($form[$key]['author']); $row[] = drupal_render($form[$key]['date']); $row[] = drupal_render($form[$key]['position']); $row[] = drupal_render($form[$key]['edit']); $row[] = drupal_render($form[$key]['remove']); $rows[] = array( 'data' => $row, 'class' => 'draggable', ); } } if (empty($rows)) { $rows[] = array(array('data' => t('No nodes in this nodequeue.'), 'colspan' => '4')); } $header = array(t('Title'), t('Author'), t('Date'), t('Position'), array('data' => t('Operations'), 'colspan' => '2')); $output .= theme('table', $header, $rows, array('id' => 'nodequeue-dragdrop')); $output .= drupal_render($form); return $output; }