### Eclipse Workspace Patch 1.0 #P prev_next Index: prev_next.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/prev_next/prev_next.module,v retrieving revision 1.1 diff -u -r1.1 prev_next.module --- prev_next.module 7 May 2009 22:12:04 -0000 1.1 +++ prev_next.module 25 Oct 2009 17:35:53 -0000 @@ -2,7 +2,8 @@ // $Id: prev_next.module,v 1.1 2009/05/07 22:12:04 kbahey Exp $ define('PREV_NEXT_BATCH_SIZE_DEFAULT', 200); -define('PREV_NEXT_NODE_TYPE', 'prev_next_node_type_'); +define('PREV_NEXT_INDEXING_CRITERIA_DEFAULT', 'nid'); +define('PREV_NEXT_NODE_TYPE', 'prev_next_node_type_'); /** * Implementation of hook_menu(). @@ -37,7 +38,7 @@ ); $max_nid = variable_get('prev_next_index_nid', 0); - $cond = _prev_next_node_types_sql(); + $cond = _prev_next_node_types_sql(0); $total = db_result(db_query("SELECT COUNT(nid) FROM {node} WHERE status = 1 $cond")); $completed = db_result(db_query("SELECT COUNT(nid) FROM {prev_next_node}")); @@ -74,17 +75,62 @@ $form['node_types'] = array( '#type' => 'fieldset', '#title' => t('Content types'), - '#description' => t('Content types to include in prev/next. If you do not specify content types, then all of them will be included.'), + '#description' => t('Define settings for each content type. If none of them is included, then all of them will be.'), ); foreach (node_get_types() as $type => $name) { - $form['node_types'][PREV_NEXT_NODE_TYPE . $type] = array( + + $form['node_types'][$type] = array( + '#type' => 'fieldset', + '#description' => t('Note: changing one of these values will reset the entire Prev/Next index.'), + '#title' => node_get_types('name', $type), + '#collapsible' => TRUE, + '#collapsed' => !variable_get(PREV_NEXT_NODE_TYPE . $type, 0) + ); + + $form['node_types'][$type][PREV_NEXT_NODE_TYPE . $type] = array( '#type' => 'checkbox', - '#title' => node_get_types('name', $type), + '#title' => t('Include'), '#default_value' => variable_get(PREV_NEXT_NODE_TYPE . $type, 0), ); + $form['node_types'][$type][PREV_NEXT_NODE_TYPE . $type . '_current'] = array( + '#type' => 'hidden', + '#default_value' => variable_get(PREV_NEXT_NODE_TYPE . $type . '_current', + variable_get(PREV_NEXT_NODE_TYPE . $type, 0)), + ); + + $form['node_types'][$type][PREV_NEXT_NODE_TYPE . $type . '_indexing_criteria'] = array( + '#title' => t('Indexing criteria'), + '#type' => 'select', + '#options' => array( + 'nid' => t('Node ID'), + 'created' => t('Post date'), + 'changed' => t('Updated date'), + 'title' => t('Title') + ), + '#default_value' => variable_get(PREV_NEXT_NODE_TYPE . $type . '_indexing_criteria',PREV_NEXT_INDEXING_CRITERIA_DEFAULT) + ); + $form['node_types'][$type][PREV_NEXT_NODE_TYPE . $type . '_indexing_criteria_current'] = array( + '#type' => 'hidden', + '#value' => variable_get(PREV_NEXT_NODE_TYPE . $type . '_indexing_criteria_current', + variable_get(PREV_NEXT_NODE_TYPE . $type . '_indexing_criteria',PREV_NEXT_INDEXING_CRITERIA_DEFAULT)) + ); + + $form['node_types'][$type][PREV_NEXT_NODE_TYPE . $type . '_same_type'] = array( + '#type' => 'checkbox', + '#title' => t('Only nodes with same content type'), + '#default_value' => variable_get(PREV_NEXT_NODE_TYPE . $type . '_same_type', 0), + ); + $form['node_types'][$type][PREV_NEXT_NODE_TYPE . $type . '_same_type_current'] = array( + '#type' => 'hidden', + '#default_value' => variable_get(PREV_NEXT_NODE_TYPE . $type . '_same_type_current', + variable_get(PREV_NEXT_NODE_TYPE . $type . '_same_type', 0)) + ); + } + $form['#submit'][] = 'prev_next_admin_submit'; + return system_settings_form($form); } @@ -105,6 +151,29 @@ } } +/** + * Submit callback. + */ +function prev_next_admin_submit($form, &$form_state) { + $rebuild = FALSE; + + // Test sensitive values. + foreach (node_get_types() as $type => $name) { + if ($form_state['values'][PREV_NEXT_NODE_TYPE . $type . '_current'] != $form_state['values'][PREV_NEXT_NODE_TYPE . $type] + || $form_state['values'][PREV_NEXT_NODE_TYPE . $type . '_indexing_criteria_current'] != $form_state['values'][PREV_NEXT_NODE_TYPE . $type . '_indexing_criteria'] + || $form_state['values'][PREV_NEXT_NODE_TYPE . $type . '_same_type_current'] != $form_state['values'][PREV_NEXT_NODE_TYPE . $type . '_same_type'] + ) + $rebuild = TRUE; + } + + // If the search criterias has been changed, re-index. + if ($rebuild) { + prev_next_reindex(); + drupal_set_message(t('The Prev/Next index will be rebuilt.')); + } + $form_state['redirect'] = 'admin/settings/prev_next'; +} + function prev_next_reindex_confirm() { return confirm_form(array(), t('Are you sure you want to re-index Prev/Next?'), 'admin/settings/prev_next', t(' The entire Prev/Next index will be reset and rebuilt incrementally as cron runs. action cannot be undone.'), t('Re-index'), t('Cancel')); @@ -138,7 +207,7 @@ if ($max_nid) { $batch_size = variable_get('prev_next_batch_size', PREV_NEXT_BATCH_SIZE_DEFAULT); $last_nid = FALSE; - $cond = _prev_next_node_types_sql(); + $cond = _prev_next_node_types_sql(0); timer_start('prev_next_cron'); $result = db_query("SELECT nid FROM {node} WHERE nid <= %d AND status = 1 $cond ORDER BY nid DESC LIMIT %d", @@ -167,6 +236,15 @@ // If all nodes have been indexed, set to zero to skip future cron runs. variable_set('prev_next_index_nid', 0); } + + $total = db_result(db_query("SELECT COUNT(nid) FROM {node} WHERE status = 1 $cond")); + $completed = db_result(db_query("SELECT COUNT(nid) FROM {prev_next_node}")); + $remaining = max(0, $total - $completed); + drupal_set_message(t('Indexed %count nodes for the Prev/Next index. There are %remaining items left to index.', array( + '%count' => $count, + '%remaining' => $remaining + ))); + } } @@ -174,11 +252,18 @@ * Create or update the prev_next records. */ function _prev_next_add($nid) { - $cond = _prev_next_node_types_sql(); + $node_type = db_result(db_query("SELECT type FROM {node} WHERE nid = %d LIMIT 1", $nid)); + $search_criteria = variable_get(PREV_NEXT_NODE_TYPE . $node_type . '_indexing_criteria', PREV_NEXT_INDEXING_CRITERIA_DEFAULT); - $next_nid = db_result(db_query("SELECT nid FROM {node} WHERE nid > %d AND status = 1 $cond ORDER BY nid ASC LIMIT 1", $nid)); + $criteria_value = db_result(db_query("SELECT %s FROM {node} WHERE nid = %d LIMIT 1", $search_criteria, $nid)); + + $cond = _prev_next_node_types_sql($node_type); + + $next_nid = db_result(db_query("SELECT nid FROM {node} WHERE %s > %s AND status = 1 $cond ORDER BY %s ASC LIMIT 1", + $search_criteria, $criteria_value, $search_criteria)); - $prev_nid = db_result(db_query("SELECT nid FROM {node} WHERE nid < %d AND status = 1 $cond ORDER BY nid DESC LIMIT 1", $nid)); + $prev_nid = db_result(db_query("SELECT nid FROM {node} WHERE %s < %s AND status = 1 $cond ORDER BY %s DESC LIMIT 1", + $search_criteria, $criteria_value, $search_criteria)); // Update the node-level data $exists = db_result(db_query('SELECT COUNT(*) FROM {prev_next_node} WHERE nid = %d', $nid)); @@ -288,17 +373,24 @@ /* * Helper function to return a SQL clause for types to be indexed */ -function _prev_next_node_types_sql() { - $types = _prev_next_node_types(); - - $quoted_types = array(); - foreach(_prev_next_node_types() as $type) { - $quoted_types[] = "'" . $type . "'"; - } - $cond = ''; - if (count($types)) { - $cond = ' AND type IN (' . implode(',', $quoted_types) . ')'; - } +function _prev_next_node_types_sql($node_type) { + + $same_type = variable_get(PREV_NEXT_NODE_TYPE . $node_type . '_same_type', 0); + + if(!$same_type) { + + $types = _prev_next_node_types(); + + $quoted_types = array(); + foreach(_prev_next_node_types() as $type) { + $quoted_types[] = "'" . $type . "'"; + } + $cond = ''; + if (count($types)) { + $cond = ' AND type IN (' . implode(',', $quoted_types) . ')'; + } + + } else $cond = " AND type = '" . $node_type . "'"; return $cond; }