? Zend
? mlt.patch
? move-mlt-framework-453338-11.patch
? move-mlt-framework-453338-12.patch
? now.diff
Index: CHANGELOG.txt
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/CHANGELOG.txt,v
retrieving revision 1.1.2.69
diff -u -p -r1.1.2.69 CHANGELOG.txt
--- CHANGELOG.txt	6 May 2009 16:34:19 -0000	1.1.2.69
+++ CHANGELOG.txt	7 May 2009 16:05:49 -0000
@@ -8,6 +8,7 @@ Apache Solr integration 6.x-1.x, xxxx-xx
 
 Apache Solr integration 6.x-1.0-xxxxx, 2009-xx-xx
 ------------------------------
+#453338 by pwolanin and JacobSingh, move mlt functionality into the framework module.
 #365495 by pwolanin, improve admin screens and usability of field weights.
 #454608 by pwolanin, fix current search block.
 #453182 by pwolanin, use stored path rather than forcing node/$nid.
Index: apachesolr.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/apachesolr.admin.inc,v
retrieving revision 1.1.2.18
diff -u -p -r1.1.2.18 apachesolr.admin.inc
--- apachesolr.admin.inc	7 May 2009 12:08:42 -0000	1.1.2.18
+++ apachesolr.admin.inc	7 May 2009 16:05:50 -0000
@@ -66,6 +66,13 @@ function apachesolr_settings() {
     '#default_value' => variable_get('apachesolr_set_nodeapi_messages', 1),
     '#options' => array(0 => t('Disabled'), 1 => t('Enabled')),
   );
+  // Add a link to add more mlt blocks.
+  $form['mlt_link'] = array(
+    '#type' => 'item',
+    '#value' => l(t('Add a new content recommendation block'), 'admin/settings/apachesolr/mlt/add_block'),
+    '#description' => format_plural(count(apachesolr_mlt_list_blocks()),  'You currently have 1 block.', 'You currenly have @count blocks.'),
+  );
+
   return system_settings_form($form);
 }
 
@@ -373,7 +380,7 @@ function _apachesolr_field_name_map($fie
   if (!isset($map)) {
     $map = array(
       'body' => t('Body text - the full, rendered content'),
-      'title' => t('Content title'),
+      'title' => t('Title'),
       'name' => t('Author name'),
       'path_alias' => t('Path alias'),
       'taxonomy_names' => t('All taxonomy term names'),
@@ -395,3 +402,206 @@ function _apachesolr_field_name_map($fie
   }
   return isset($map[$field_name]) ? $map[$field_name] : $field_name;
 }
+
+/**
+ * MoreLikeThis administration and utility functions.
+ */
+
+function apachesolr_mlt_add_block_form() {
+  $form = apachesolr_mlt_block_form();
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Save'),
+    '#weight' => '5',
+  );
+  return $form;
+}
+
+function apachesolr_mlt_add_block_form_submit($form, &$form_state) {
+  apachesolr_mlt_save_block($form_state['values']);
+  drupal_set_message('New content recommendation block created.  Drag it into a region to enable it');
+  $form_state['redirect'] = 'admin/build/block';
+}
+
+/**
+ * Form to edit moreLikeThis block settings.
+ *
+ * @param int $delta If editing, the id of the block to edit.
+ *
+ * @return array The form used for editing.
+ * TODO:
+ *   Add term boost settings.
+ *   Enable the user to specify a query, rather then forcing suggestions based
+ *     on the node id.
+ *
+ */
+function apachesolr_mlt_block_form($delta = NULL) {
+  if (isset($delta)) {
+    $block = apachesolr_mlt_load_block($delta);
+    if (!$block) {
+      return array();
+    }
+  }
+  else{
+    $block = apachesolr_mlt_block_defaults();
+  }
+
+  $form['name'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Block Name'),
+    '#description' => t('The block name displayed to site users.'),
+    '#required' => TRUE,
+    '#default_value' => $block['name'],
+    '#weight' => '-2',
+  );
+  $form['num_results'] = array(
+    '#type' => 'select',
+    '#title' => t('Maximum number of related items to display'),
+    '#default_value' => $block['num_results'],
+    '#options' => drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)),
+    '#weight' => -1,
+    );
+  $form['mlt_fl'] = array(
+    '#type' => 'checkboxes',
+    '#title' => t('Fields for finding related content'),
+    '#description' => t('Choose the fields to be used in calculating similarity. The default combination of %taxonomy_names and %title will provide relevant results for typical sites.', array("%taxonomy_names" => _apachesolr_field_name_map("taxonomy_names"), "%title" => _apachesolr_field_name_map("title"))),
+    '#options' => apachesolr_mlt_get_fields(),
+    '#required' => TRUE,
+    '#default_value' =>  $block['mlt_fl'],
+  );
+  $form['advanced'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Advanced Configuration'),
+    '#weight' => '1',
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+  );
+  $options = drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7));
+  $form['advanced']['mlt_mintf'] = array(
+    '#type' => 'select',
+    '#title' => t('Minimum Term Frequency'),
+    '#description' => t('A word must appear this many times in any given document before the document is considered relevant for comparison.'),
+    '#default_value' => $block['mlt_mintf'],
+    '#options' => $options,
+  );
+  $form['advanced']['mlt_mindf'] = array(
+    '#type' => 'select',
+    '#title' => t('Minimum Document Frequency'),
+    '#description' => t('A word must occur in at least this many documents before it will be used for similarity comparison.'),
+    '#default_value' => $block['mlt_mindf'],
+    '#options' => $options,
+  );
+  $form['advanced']['mlt_minwl'] = array(
+    '#type' => 'select',
+    '#title' => t('Minimum Word Length'),
+    '#description' => 'You can use this to eliminate short words such as "the" and "it" from similarity comparisons. Words must be at least this number of characters or they will be ignored.',
+    '#default_value' => $block['mlt_minwl'],
+    '#options' => $options,
+  );
+  $form['advanced']['mlt_maxwl'] = array(
+    '#type' => 'select',
+    '#title' => t('Maximum World Length'),
+    '#description' => t('You can use this to eliminate very long words from similarity comparisons. Words of more than this number of characters will be ignored.'),
+    '#default_value' => $block['mlt_maxwl'],
+    '#options' => drupal_map_assoc(array(8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)),
+  );
+  $form['advanced']['mlt_maxqt'] = array(
+    '#type' => 'select',
+    '#title' => t('Maximum number of query terms'),
+    '#description' => t('The maximum number of query terms that will be included in any query. Lower numbers will result in fewer recommendations but will get results faster. If a content recommendation is not returning any recommendations, you can either check more "Comparison fields" checkboxes or increase the maximum number of query terms here.'),
+    '#options' => drupal_map_assoc(array(5, 10, 15, 20, 25, 30, 35, 40, 45, 50)),
+    '#default_value' => $block['mlt_maxqt'],
+  );
+
+  return $form;
+}
+
+/**
+ * Merge supplied settings with the standard defaults..
+ */
+function apachesolr_mlt_block_defaults($block = array()) {
+  return $block + array(
+    'name' => '',
+    'num_results' => '5',
+    'mlt_fl' =>  array(
+      'title' => 'title',
+      'taxonomy_names' => 'taxonomy_names',
+    ),
+    'mlt_mintf' => '1',
+    'mlt_mindf' => '1',
+    'mlt_minwl' => '3',
+    'mlt_maxwl' => '15',
+    'mlt_maxqt' => '30',
+  );
+}
+
+/**
+ * Constructs a list of field names used on the settings form.
+ *
+ * @return array An array containing a the fields in the solr instance.
+ */
+function apachesolr_mlt_get_fields() {
+  $solr = apachesolr_get_solr();
+  $fields = $solr->getFields();
+  $rows = array();
+  foreach ($fields as $field_name => $field) {
+    if ($field->schema{4} == 'V')
+    $rows[$field_name] = _apachesolr_field_name_map($field_name);
+  }
+  ksort($rows);
+  return $rows;
+}
+
+/**
+ * A helper function to save MLT block data.
+ *
+ * If passed a block delta, the function will update block settings. If it is
+ * not passed a block delta, the function will create a new block.
+ *
+ * @param array $block_settings An array containing the settings required to form
+ * a moreLikeThis request.
+ *
+ * @param int $delta The id of the block you wish to update.
+ */
+function apachesolr_mlt_save_block($block_settings = array(), $delta = NULL) {
+  $blocks = variable_get('apachesolr_mlt_blocks', array());
+  if (is_null($delta)) {
+    $count = 0;
+    ksort($blocks);
+    // Construct a new array key.
+    if (end($blocks)) {
+      list(, $count) = explode('-', key($blocks));
+    }
+    $delta = sprintf('mlt-%03d', 1 + $count);
+  }
+  $defaults = apachesolr_mlt_block_defaults();
+  // Remove stray form values.
+  $blocks[$delta] = array_intersect_key($block_settings, $defaults) + $defaults;
+  // Eliminate non-selected fields.
+  $blocks[$delta]['mlt_fl'] = array_filter($blocks[$delta]['mlt_fl']);
+  variable_set('apachesolr_mlt_blocks', $blocks);
+}
+
+function apachesolr_mlt_delete_block_form($form_state, $delta) {
+  if ($block = apachesolr_mlt_load_block($delta)) {
+    $form['delta'] = array(
+      '#type' => 'value',
+      '#value' => $delta
+    );
+
+    return confirm_form($form,
+      t('Are you sure you want to delete the Apache Solr content recommendation block %name?', array('%name' => $block['name'])),
+      'admin/build/block',
+      t('The block will be deleted. This action cannot be undone.'),
+      t('Delete'), t('Cancel'));
+  }
+}
+
+function apachesolr_mlt_delete_block_form_submit($form, &$form_state) {
+  $blocks = variable_get('apachesolr_mlt_blocks', array());
+  unset($blocks[$form_state['values']['delta']]);
+  variable_set('apachesolr_mlt_blocks', $blocks);
+  drupal_set_message(t('The block has been deleted.'));
+  $form_state['redirect'] = 'admin/build/block';
+}
+
Index: apachesolr.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/apachesolr.install,v
retrieving revision 1.1.4.15
diff -u -p -r1.1.4.15 apachesolr.install
--- apachesolr.install	14 Apr 2009 00:12:18 -0000	1.1.4.15
+++ apachesolr.install	7 May 2009 16:05:50 -0000
@@ -12,6 +12,10 @@
 function apachesolr_install() {
   // Create tables.
   drupal_install_schema('apachesolr');
+  // Create one MLT block.
+  require_once(drupal_get_path('module', 'apachesolr') .'/apachesolr.admin.inc');
+  apachesolr_mlt_save_block(array('name' => t('More like this')));
+
   drupal_set_message(t('Search is enabled. You\'re site is <a href="!index_settings_link">currently 0% indexed</a>.', array('!index_settings_link' => url('admin/settings/apachesolr/index'))));
 }
 
@@ -79,6 +83,7 @@ function apachesolr_uninstall() {
   variable_del('apachesolr_facet_query_limit_default');  
   variable_del('apachesolr_site_hash');
   variable_del('apachesolr_index_last');
+  variable_del('apachesolr_mlt_blocks');
   // Remove tables.
   drupal_uninstall_schema('apachesolr');
 }
@@ -160,3 +165,24 @@ function apachesolr_update_6003() {
   }
   return $ret;
 }
+
+/**
+ *  Subsume MLT functionality..
+ */
+function apachesolr_update_6004() {
+  $ret = array();
+  if (db_result(db_query("SELECT status FROM {system} WHERE name = 'apachesolr_mlt'"))) {
+    require_once(drupal_get_path('module', 'apachesolr') .'/apachesolr.admin.inc');
+    $result = db_query('SELECT id, data FROM {apachesolr_mlt} ORDER BY id ASC');
+    while ($row = db_fetch_array($result)) {
+      $delta = sprintf('mlt-%03d', $row['id']);
+      apachesolr_mlt_save_block(unserialize($row['data']), $delta);
+      $ret[] = update_sql("UPDATE {blocks} SET module = 'apachesolr', delta = '". $delta ."' WHERE module = 'apachesolr_mlt' AND delta ='". $row['id'] ."'");
+    }
+  }
+  if (db_table_exists("{apachesolr_mlt}")) {
+    $ret[] = update_sql("DROP TABLE {apachesolr_mlt}");
+  }
+  $ret[] = update_sql("DELETE FROM {system} WHERE name = 'apachesolr_mlt'");
+  return $ret;
+}
Index: apachesolr.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/apachesolr.module,v
retrieving revision 1.1.2.12.2.139
diff -u -p -r1.1.2.12.2.139 apachesolr.module
--- apachesolr.module	6 May 2009 16:34:19 -0000	1.1.2.12.2.139
+++ apachesolr.module	7 May 2009 16:05:50 -0000
@@ -63,7 +63,20 @@ function apachesolr_menu() {
     'file'               => 'apachesolr.admin.inc',
     'type'               => MENU_DEFAULT_LOCAL_TASK,
   );
-  
+  $items['admin/settings/apachesolr/mlt/add_block'] = array(
+    'page callback'      => 'drupal_get_form',
+    'page arguments'     => array('apachesolr_mlt_add_block_form'),
+    'access arguments'   => array('administer search'),
+    'file'               => 'apachesolr.admin.inc',
+    'type'               => MENU_CALLBACK,
+  );
+  $items['admin/settings/apachesolr/mlt/delete_block/%'] = array(
+    'page callback'      => 'drupal_get_form',
+    'page arguments'     => array('apachesolr_mlt_delete_block_form', 5),
+    'access arguments'   => array('administer search'),
+    'file'               => 'apachesolr.admin.inc',
+    'type'               => MENU_CALLBACK,
+  );
   return $items;
 }
 
@@ -499,9 +512,13 @@ function apachesolr_get_enabled_facets($
  * Implementation of hook_block().
  */
 function apachesolr_block($op = 'list', $delta = 0, $edit = array()) {
+  static $access;
+
   switch ($op) {
     case 'list':
-      // Add the blocks
+      // Get all of the moreLikeThis blocks that the user has created
+      $blocks = apachesolr_mlt_list_blocks();
+      // Add the sort block.
       $blocks['sort'] = array(
         'info' => t('Apache Solr Core: Sorting'),
         'cache' => BLOCK_CACHE_PER_PAGE,
@@ -509,7 +526,26 @@ function apachesolr_block($op = 'list', 
       return $blocks;
 
     case 'view':
-      if (apachesolr_has_searched()) {
+      if ($delta != 'sort' && ($node = menu_get_object()) && (!arg(2) || arg(2) == 'view')) {
+        $suggestions = array();
+        // Determine whether the user can view the current node.
+        if (!isset($access)) {
+          $access = node_access('view', $node);
+        }
+        $block = apachesolr_mlt_load_block($delta);
+        if ($access && $block) {
+          $docs = apachesolr_mlt_suggestions($block, apachesolr_document_id($node->nid));
+          if (!empty($docs)) {
+            $suggestions['subject'] = check_plain($block['name']);
+            $suggestions['content'] = theme('apachesolr_mlt_recommendation_block', $docs);
+            if (user_access('administer search')) {
+               $suggestions['content'] .= l(t('Configure this block'),'admin/build/block/configure/apachesolr/' . $delta, array('attributes' => array('class' => 'apachesolr-mlt-admin-link')));
+            }
+          }
+        }
+        return $suggestions;
+      }
+      elseif (apachesolr_has_searched() && $delta == 'sort') {
         // Get the query and response. Without these no blocks make sense.
         $response = apachesolr_static_response_cache();
         if (empty($response) || ($response->response->numFound < 2)) {
@@ -517,47 +553,52 @@ function apachesolr_block($op = 'list', 
         }
 
         $query = apachesolr_current_query();
+        $sorts = $query->get_available_sorts();
 
-        switch ($delta) {
-          case 'sort':
-            $sorts = $query->get_available_sorts();
-
-            $solrsorts = array();
-            $sort_parameter = isset($_GET['solrsort']) ? check_plain($_GET['solrsort']) : FALSE;
-            foreach (explode(',', $sort_parameter) as $solrsort) {
-              $parts = explode(' ', $solrsort);
-              if (!empty($parts[0]) && !empty($parts[1])) {
-                $solrsorts[$parts[0]] = $parts[1];
-              }
-            }
-
-            $sort_links = array();
-            $path = $query->get_path();
-            $new_query = clone $query;
-            foreach ($sorts as $type => $sort) {
-              $new_sort = isset($solrsorts[$type]) ? $solrsorts[$type] == 'asc' ? 'desc' : 'asc' : $sort['default'];
-              $new_query->set_solrsort($type == "relevancy" ? '' : "{$type} {$new_sort}");
-              $active = isset($solrsorts[$type]) || ($type == "relevancy" && !$solrsorts);
-              $direction = isset($solrsorts[$type]) ? $solrsorts[$type] : '';
-              $sort_links[$type] = array(
-                'name' => $sort['name'],
-                'path' => $path,
-                'querystring' => $new_query->get_url_querystring(),
-                'active' => $active,
-                'direction' => $direction
-              );
-            }
-            // Allow other modules to add or remove sorts.
-            drupal_alter('apachesolr_sort_links', $sort_links);
-            foreach ($sort_links as $type => $link) {
-              $themed_links[$type] = theme('apachesolr_sort_link', $link['name'], $link['path'], $link['querystring'], $link['active'], $link['direction']);
-            }
-            return array('subject' => t('Sort by'),
-                         'content' => theme('apachesolr_sort_list', $themed_links));
-          default:
-            break;
+        $solrsorts = array();
+        $sort_parameter = isset($_GET['solrsort']) ? check_plain($_GET['solrsort']) : FALSE;
+        foreach (explode(',', $sort_parameter) as $solrsort) {
+          $parts = explode(' ', $solrsort);
+          if (!empty($parts[0]) && !empty($parts[1])) {
+            $solrsorts[$parts[0]] = $parts[1];
+          }
         }
 
+        $sort_links = array();
+        $path = $query->get_path();
+        $new_query = clone $query;
+        foreach ($sorts as $type => $sort) {
+          $new_sort = isset($solrsorts[$type]) ? $solrsorts[$type] == 'asc' ? 'desc' : 'asc' : $sort['default'];
+          $new_query->set_solrsort($type == "relevancy" ? '' : "{$type} {$new_sort}");
+          $active = isset($solrsorts[$type]) || ($type == "relevancy" && !$solrsorts);
+          $direction = isset($solrsorts[$type]) ? $solrsorts[$type] : '';
+          $sort_links[$type] = array(
+            'name' => $sort['name'],
+            'path' => $path,
+            'querystring' => $new_query->get_url_querystring(),
+            'active' => $active,
+            'direction' => $direction
+          );
+        }
+        // Allow other modules to add or remove sorts.
+        drupal_alter('apachesolr_sort_links', $sort_links);
+        foreach ($sort_links as $type => $link) {
+          $themed_links[$type] = theme('apachesolr_sort_link', $link['name'], $link['path'], $link['querystring'], $link['active'], $link['direction']);
+        }
+        return array('subject' => t('Sort by'),
+                     'content' => theme('apachesolr_sort_list', $themed_links));
+      }
+      break;
+    case 'configure':
+      if ($delta != 'sort') {
+        require_once(drupal_get_path('module', 'apachesolr') .'/apachesolr.admin.inc');
+        return apachesolr_mlt_block_form($delta);
+      }
+      break;
+    case 'save':
+      if ($delta != 'sort') {
+        require_once(drupal_get_path('module', 'apachesolr') .'/apachesolr.admin.inc');
+        apachesolr_mlt_save_block($edit, $delta);
       }
       break;
   }
@@ -848,7 +889,6 @@ function apachesolr_date_gap_drilldown($
   return isset($drill[$gap]) ? $drill[$gap] : NULL;
 }
 
-
 /**
  * Used by the 'configure' $op of hook_block so that modules can generically set
  * facet limits on their blocks.
@@ -1145,9 +1185,115 @@ function apachesolr_theme() {
     'apachesolr_sort_link' => array(
       'arguments' => array('text' => NULL, 'path' => NULL, 'querystring' => '', 'active' => FALSE, 'direction' => ''),
     ),
+    'apachesolr_mlt_recommendation_block' => array(
+      'arguments' => array('docs' => NULL),
+    ),
   );
 }
 
+/**
+ * Performs a moreLikeThis query using the settings and retrieves documents.
+ *
+ * @param $settings
+ *   An array of settings.
+ * @param $id
+ *   The Solr ID of the document for which you want related content.
+ *   For a node that is apachesolr_document_id($node->nid)
+ *
+ * @return An array of response documents, or NULL
+ */
+function apachesolr_mlt_suggestions($settings, $id) {
+
+  try {
+    $solr = apachesolr_get_solr();
+    $fields = array(
+      'mlt_mintf' => 'mlt.mintf',
+      'mlt_mindf' => 'mlt.mindf',
+      'mlt_minwl' => 'mlt.minwl',
+      'mlt_maxwl' => 'mlt.maxwl',
+      'mlt_maxqt' => 'mlt.maxqt',
+      'mlt_boost' => 'mlt.boost',
+      'mlt_qf' => 'mlt.qf',
+    );
+
+    $params = array(
+      'qt' => 'mlt',
+      'fl' => 'nid,title,path,url',
+      'mlt.fl' => implode(',', $settings['mlt_fl']),
+    );
+
+    foreach ($fields as $form_key => $name) {
+      if (!empty($settings[$form_key])) {
+        $params[$name] = $settings[$form_key];
+      }
+    }
+    $query = apachesolr_drupal_query('id:' . $id);
+
+    // This hook allows modules to modify the query and params objects.
+    apachesolr_modify_query($query, $params, 'apachesolr_mlt');
+    if (empty($query)) {
+      return;
+    }
+
+    $response = $solr->search($query->get_query_basic(), 0, $settings['num_results'], $params);
+
+    if ($response->response) {
+      $docs = (array) end($response->response);
+      return $docs;
+    }
+  } 
+  catch ( Exception $e ) {
+    watchdog('Apache Solr', $e->getMessage(), NULL, WATCHDOG_ERROR );
+  }
+}
+
+/**
+ * Implementation of hook_form_[form_id]_alter
+ */
+function apachesolr_form_block_admin_display_form_alter(&$form) {
+  foreach ($form as $key => $block) {
+    if ((strpos($key, "apachesolr_mlt-") === 0) && $block['module']['#value'] == 'apachesolr') {
+      $form[$key]['delete'] = array('#value' => l(t('delete'), 'admin/settings/apachesolr/mlt/delete_block/'. $block['delta']['#value']));
+    }
+  }
+}
+
+/**
+ * Implementation of hook_form_[form_id]_alter().
+ *
+ * Hide the core 'title' field in favor of our 'name' field..
+ */
+function apachesolr_form_block_admin_configure_alter(&$form, $form_state) {
+  if ($form['module']['#value'] == 'apachesolr' && $form['delta']['#value'] != 'sort') {
+    $form['block_settings']['title']['#access'] = FALSE;
+  }
+}
+
+/**
+ * Returns a list of blocks. Used by hook_block
+ */
+function apachesolr_mlt_list_blocks() {
+  $blocks = variable_get('apachesolr_mlt_blocks', array());
+  foreach ($blocks as $delta => $settings) {
+    $blocks[$delta] += array('info' => t('Apache Solr recommendations: !name', array('!name' => $settings['name'])) , 'cache' => BLOCK_CACHE_PER_PAGE);
+  }
+  return $blocks;
+}
+
+function apachesolr_mlt_load_block($delta) {
+  $blocks = variable_get('apachesolr_mlt_blocks', array());
+  return isset($blocks[$delta]) ? $blocks[$delta] : FALSE;
+}
+
+function theme_apachesolr_mlt_recommendation_block($docs) {
+  $links = array();
+  foreach ($docs as $result) {
+    // Suitable for single-site mode.
+    $links[] = l($result->title, $result->path);
+  }
+  return theme('item_list', $links);
+}
+
 function theme_apachesolr_facet_item($name, $count, $path, $querystring = '', $active = FALSE, $unclick_link = NULL, $num_found = NULL, $options = array()) {
 
   if ($active) {
Index: contrib/apachesolr_mlt/apachesolr_mlt.info
===================================================================
RCS file: contrib/apachesolr_mlt/apachesolr_mlt.info
diff -N contrib/apachesolr_mlt/apachesolr_mlt.info
--- contrib/apachesolr_mlt/apachesolr_mlt.info	27 Jan 2009 21:32:35 -0000	1.1.4.5
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,6 +0,0 @@
-; $Id: apachesolr_mlt.info,v 1.1.4.5 2009/01/27 21:32:35 pwolanin Exp $
-name = Apache Solr more like this
-description = Use Solr to make content recommendations
-dependencies[] = apachesolr
-package = Apache Solr
-core = 6.x
\ No newline at end of file
Index: contrib/apachesolr_mlt/apachesolr_mlt.install
===================================================================
RCS file: contrib/apachesolr_mlt/apachesolr_mlt.install
diff -N contrib/apachesolr_mlt/apachesolr_mlt.install
--- contrib/apachesolr_mlt/apachesolr_mlt.install	10 Feb 2009 20:25:48 -0000	1.1.4.4
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,51 +0,0 @@
-<?php
-//$Id: apachesolr_mlt.install,v 1.1.4.4 2009/02/10 20:25:48 pwolanin Exp $
-
-function apachesolr_mlt_install() {
-  // Create tables.
-  $pass = drupal_install_schema('apachesolr_mlt');
-  if ($pass) {
-    drupal_set_message(t('Created the apachesolr_mlt table'));
-    drupal_load('module', 'apachesolr_mlt');
-    $block = array(
-      'name' => t('More like this'),
-      'num_results' => '5',
-      'mlt_fl' =>  array(
-        'title' => 'title',
-        'taxonomy_names' => 'taxonomy_names',
-      ),
-      'mlt_mintf' => '1',
-      'mlt_mindf' => '1',
-      'mlt_minwl' => '3',
-      'mlt_maxwl' => '15',
-      'mlt_maxqt' => '30',
-    );
-    apachesolr_mlt_save_block($block, NULL);
-  }
-}
-
-function apachesolr_mlt_schema() {
-  $schema['apachesolr_mlt'] = array(
-    'description' => t('Tracks custom content recommendation blocks.'),
-    'fields' => array(
-      'id' => array(
-        'description' => t('The primary identifier for a custom block.'),
-        'type' => 'serial',
-        'unsigned' => TRUE,
-        'not null' => TRUE),
-      'data' => array(
-        'description' => t('The serialized data for a block.'),
-        'type' => 'text',
-        'size' => 'big',
-        'not null' => TRUE,
-      ),
-    ),
-    'primary key' => array('id'),
-  );
-  return $schema;
-}
-
-function apachesolr_mlt_uninstall() {
-  // Remove tables.
-  drupal_uninstall_schema('apachesolr_mlt');
-}
\ No newline at end of file
Index: contrib/apachesolr_mlt/apachesolr_mlt.module
===================================================================
RCS file: contrib/apachesolr_mlt/apachesolr_mlt.module
diff -N contrib/apachesolr_mlt/apachesolr_mlt.module
--- contrib/apachesolr_mlt/apachesolr_mlt.module	31 Mar 2009 16:06:37 -0000	1.1.4.27
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,382 +0,0 @@
-<?php
-// $Id: apachesolr_mlt.module,v 1.1.4.27 2009/03/31 16:06:37 pwolanin Exp $
-
-/**
- * Implementation of hook_menu()
- */
-function apachesolr_mlt_menu() {
-  $items = array();
-
-  $items['admin/settings/apachesolr/mlt'] = array(
-    'title' => 'More Like This',
-    'description' => 'Configure content recommendation blocks using the Apache Solr "More Like This" handler.',
-    'page callback' => 'apachesolr_mlt_settings',
-    'access arguments' => array('administer search'),
-    'type' => MENU_LOCAL_TASK,
-  );
-  $items['admin/settings/apachesolr/mlt/configure_block'] = array(
-    'type' => MENU_CALLBACK,
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('apachesolr_mlt_block_form', 5),
-    'access arguments' => array('administer search'),
-    );
-  $items['admin/settings/apachesolr/mlt/delete_block'] = array(
-    'type' => MENU_CALLBACK,
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('apachesolr_mlt_delete_block_form', 5),
-    'access arguments' => array('administer search'),
-  );
-  return $items;
-}
-
-/**
- * Implementation of hook_block
- */
-function apachesolr_mlt_block($op = 'list', $delta = 0, $edit = array()) {
-  static $access;
-
-  if ($op == 'list') {
-    //return all of the moreLikeThis blocks that the user has created
-    $blocks = apachesolr_mlt_list_blocks();
-    return $blocks;
-  }
-  elseif ($op == 'view' && !empty($delta) && (arg(0) == 'node')) {
-    //return the content of the block, based on the delta
-    $nid = arg(1);
-    if (is_numeric($nid) && (!arg(2) || arg(2) == 'view')) {
-      // Determine whether the user can view the current node.
-      if (!isset($access)) {
-        $node = node_load($nid);
-        $access = $node && node_access('view', $node);
-      }
-      if ($access) {
-        return apachesolr_mlt_suggestions($delta, $nid);
-      }
-    }
-  }
-}
-
-/**
- * function apachesolr_mlt_suggestions()
- * This function loads a the parameters for each moreLikeThis query, performs
- * the query, and returns a list of linked node titles.
- *
- * @param int $block_id A block ID for loading the suggestions
- *
- * @return array An array to be returned to hook_block
- */
-function apachesolr_mlt_suggestions($block_id, $nid) {
-
-  try {
-    $solr = apachesolr_get_solr();
-    $fields = array('mlt.mintf', 'mlt.mindf', 'mlt.minwl', 'mlt.maxwl', 'mlt.maxqt', 'mlt.boost', 'mlt.qf');
-    $block = apachesolr_mlt_load_block($block_id);
-
-    $params = array(
-        'qt' => 'mlt',
-        'fl' => 'nid,title,url',
-        'mlt.fl' => implode(',', $block['mlt_fl']),
-    );
-
-    foreach ($fields as $field) {
-      $drupal_fieldname = str_replace('.', '_', $field);
-      if (!empty($block[$drupal_fieldname])) {
-        $params[$field] = check_plain($block[$drupal_fieldname]);
-      }
-    }
-    $query = apachesolr_drupal_query('id:' . apachesolr_document_id($nid));
-
-    // This hook allows modules to modify the query and params objects.
-    apachesolr_modify_query($query, $params, 'apachesolr_mlt');
-    if (empty($query)) {
-      return;
-    }
-
-    $response = $solr->search($query->get_query_basic(), 0, $block['num_results'], $params);
-    $suggestions = array();
-    if ($response->response) {
-      $docs = (array) end($response->response);
-      if (!empty($docs)) {
-        $suggestions['subject'] = check_plain($block['name']);
-        $suggestions['content'] = theme('apachesolr_mlt_recommendation_block', $docs);
-        if (user_access('administer search')) {
-           $suggestions['content'] .= l(t('Configure this block'),'admin/settings/apachesolr/mlt/configure_block/' . $delta, array('attributes' => array('class' => 'apachesolr-mlt-admin-link')));
-        }
-      }
-    }
-    return $suggestions;
-  } 
-  catch ( Exception $e ) {
-    watchdog('Apache Solr', $e->getMessage(), NULL, WATCHDOG_ERROR );
-  }
-}
-
-function apachesolr_mlt_theme($existing, $type, $theme, $path) {
-  return array(
-    'apachesolr_mlt_recommendation_block' => array(
-      'arguments' => array('docs' => NULL),
-    ),
-  );
-}
-
-function theme_apachesolr_mlt_recommendation_block($docs) {
-  $links = array();
-  foreach ($docs as $result) {
-    // Suitable for single-site mode.
-    $links[] = l($result->title, 'node/' . $result->nid);
-  }
-  return theme('item_list', $links);
-}
-
-/**
- * function apachesolr_mlt_settings()
- * Returns the settings page.
- */
-function apachesolr_mlt_settings() {
-  $query = "SELECT * FROM {apachesolr_mlt}";
-  $results = db_query($query);
-  $rows = array();
-  while ($block = db_fetch_object($results)) {
-    $block->data = unserialize($block->data);
-    $rows[] = array(
-      $block->id,
-      check_plain($block->data['name']),
-      l(t('Edit'), 'admin/settings/apachesolr/mlt/configure_block/' . $block->id) .' | ' . l('Delete', 'admin/settings/apachesolr/mlt/delete_block/' . $block->id),
-    );
-  }
-  $header = array(t('Id'), t('Name'), t('Options'));
-  $output = l(t('Add block'), 'admin/settings/apachesolr/mlt/configure_block');
-  $output .= theme('table', $header, $rows);
-  return $output;
-}
-
-/**
- * function apachesolr_mlt_block_form()
- * Allows users to create and edit moreLikeThis Blocks.
- * @param int $block_id If editing, the id of the block to edit.
- *
- * @return array The form used for editing.
- * TODO:
- *   Add term boost settings.
- *   Enable the user to specify a query, rather then forcing suggestions based
- *     on the node id.
- *
- */
-function apachesolr_mlt_block_form(&$form_state, $block_id = NULL) {
-  $block = array();
-  // If editing, load the current settings for the block.
-  if ($block_id && is_numeric($block_id)) {
-    $block = apachesolr_mlt_load_block($block_id);
-    $form['block_id'] = array(
-      '#type' => 'value',
-      '#value' => $block_id,
-    );
-  }
-
-  $form['name'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Block Name'),
-    '#description' => t('The block name displayed to site users.'),
-    '#required' => TRUE,
-    '#default_value' => isset($block['name']) ? $block['name'] : '',
-    '#weight' => '-2',
-  );
-  $form['num_results'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Maximum number of results'),
-    '#default_value' => isset($block['num_results']) ? $block['num_results'] : 5,
-    '#weight' => -1,
-    );
-
-  $form['comparison'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Comparison fields'),
-    '#weight' => 0,
-    '#collapsible' => TRUE,
-    '#collapsed' => FALSE,
-    );
-  $form['comparison']['mlt_fl'] = array(
-    '#type' => 'checkboxes',
-    '#title' => t('Fields for comparison'),
-    '#description' => t('Select fields to be used in calculating similarity. The default combination of "taxonomy_names" and "title" will provide relevant results for typical sites.'),
-    '#options' => apachesolr_mlt_get_fields(),
-    '#default_value' => isset($block['mlt_fl']) ? $block['mlt_fl'] : array('title', 'taxonomy_names'),
-  );
-
-  $form['advanced'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Advanced Configuration'),
-    '#weight' => '1',
-    '#collapsible' => TRUE,
-    '#collapsed' => TRUE,
-  );
-  $form['advanced']['mlt_mintf'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Minimum Term Frequency'),
-    '#description' => t('A word must appear this many times in any given document before the document is considered relevant for comparison.'),
-    '#default_value' => isset($block['mlt_mintf']) ? (int) $block['mlt_mintf'] : 1,
-  );
-  $form['advanced']['mlt_mindf'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Minimum Document Frequency'),
-    '#description' => t('A word must occur in at least this many documents before it will be used for similarity comparison.'),
-    '#default_value' => isset($block['mlt_mindf']) ? (int) $block['mlt_mindf'] : 1,
-  );
-  $form['advanced']['mlt_minwl'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Minimum Word Length'),
-    '#description' => 'You can use this to eliminate short words such as "the" and "it" from similarity comparisons. Words must be at least this number of characters or they will be ignored.',
-    '#default_value' => isset($block['mlt_minwl']) ? (int) $block['mlt_minwl'] : 3,
-  );
-  $form['advanced']['mlt_maxwl'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Maximum World Length'),
-    '#description' => t('You can use this to eliminate very long words from similarity comparisons. Words of more than this number of characters will be ignored.'),
-    '#default_value' => isset($block['mlt_maxwl']) ? (int) $block['mlt_maxwl'] : 15,
-  );
-  $form['advanced']['mlt_maxqt'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Maximum number of query terms'),
-    '#description' => t('The maximum number of query terms that will be included in any query. Lower numbers will result in fewer recommendations but will get results faster. If a content recommendation is not returning any recommendations, you can either check more "Comparison fields" checkboxes or increase the maximum number of query terms here.'),
-    '#default_value' => isset($block['mlt_maxqt']) ? (int) $block['mlt_maxqt'] : 30,
-  );
-
-  $form['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Save'),
-    '#weight' => '5',
-  );
-
-  $form['#redirect'] = 'admin/settings/apachesolr/mlt';
-
-  return $form;
-}
-
-/**
- * function apachesolr_mlt_block_validate()
- *
- * Perform basic form field validation on the morelikethis fields.
- *
- * @param string $form_id the form ID
- * @param array $form_values an array of from values
- */
-function apachesolr_mlt_block_form_validate($form, &$form_state) {
-  if ($form_state['values']['form_id'] == 'apachesolr_mlt_block_form') {
-    foreach ($form_state['values'] as $key => $value) {
-      //make sure the user inputed a number, accept for the field list
-      if (strpos($key, 'mlt_') === 0 && $key != 'mlt_fl') {
-        if (!empty($value) && !is_numeric($value)) {
-          form_set_error($key, t("This field must contain a whole number."));
-        }
-      }
-    }
-  }
-}
-
-/**
- * function apachesolr_mlt_block_submit()
- * @param string $form_id the form ID
- * @param array $form_values an array of from values
- */
-function apachesolr_mlt_block_form_submit($form, &$form_state) {
-  if ($form_state['values']['form_id'] == 'apachesolr_mlt_block_form') {
-    $form_state['values']['mlt_fl'] = array_diff($form_state['values']['mlt_fl'], array(0));
-    apachesolr_mlt_save_block($form_state['values'], isset($form_state['values']['block_id']) ? $form_state['values']['block_id'] : NULL);
-  }
-}
-
-
-/**
- * function apachesolr_mlt_get_fields()
- * A list of field names used on the settings form.
- * @return array An array containing a the fields in the solr instance.
- */
-function apachesolr_mlt_get_fields() {
-  $solr = apachesolr_get_solr();
-  $fields = $solr->getFields();
-  $rows = array();
-  foreach ($fields as $field_name => $field) {
-    if ($field->schema{4} == 'V')
-    $rows[$field_name] = $field_name;
-  }
-
-  return $rows;
-}
-
-/**
- * function apachesolr_mlt_load_block()
- * A loader function for the apachesolr more like this module. If the function
- * is passed a proper block id, the function will return the settings for the
- * moreLikeThis request. If the block id is invalid the function returns an
- * empty array.
- *
- * @param int $block_id the id of the block you wish to load
- *
- * @return array Either the array of settings to perform the moreLikeThis request
- * or an empty array if the block id is invalid.
- */
-function apachesolr_mlt_load_block($block_id = 0) {
-  if (is_numeric($block_id)) {
-    $query_results = db_result(db_query('SELECT data FROM {apachesolr_mlt} WHERE id = %d', $block_id));
-    if (strlen($query_results)) {
-      return unserialize($query_results);
-    }
-  }
-  else {
-    return array();
-  }
-}
-
-/**
- * function apachesolr_mlt_save_block()
- * A helper function save the block data to the database.  If passed a valid
- * block id, the function will update block settings in the database. If it is
- * not passed a block id, the function will create a new block.
- *
- * @param array $block_settings An array containing the settings required to form
- * a moreLikeThis request.
- *
- * @param int $block_id The id of the block you wish to update.
- */
-function apachesolr_mlt_save_block($block_settings = array(), $block_id = 0) {
-  if (is_numeric($block_id) && $block_id > 0) {
-    db_query("UPDATE {apachesolr_mlt} SET data = '%s' WHERE id = %d", serialize($block_settings), $block_id);
-  }
-  else {
-    db_query("INSERT INTO {apachesolr_mlt} (data) VALUES ('%s')", serialize($block_settings));
-  }
-}
-
-/**
- * function apachesolr_mlt_list_blocks()
- * Returns a list of blocks. Used by hook_block
- */
-function apachesolr_mlt_list_blocks() {
-  $block_results = db_query("SELECT * FROM {apachesolr_mlt}");
-  $blocks = array();
-  while ($block = db_fetch_object($block_results)) {
-    $block->data = unserialize($block->data);
-    $blocks[$block->id] = array('info' => t('Apache Solr recommendations: !name', array('!name' => $block->data['name'])) , 'cache' => BLOCK_CACHE_PER_PAGE);
-  }
-  return $blocks;
-}
-
-function apachesolr_mlt_delete_block_form(&$form_values, $block_id = NULL) {
-  if (is_numeric($block_id)) {
-    $block = apachesolr_mlt_load_block($block_id);
-    $form['block_id'] = array(
-      '#type' => 'value',
-      '#value' => $block_id
-    );
-    $form['#redirect'] = 'admin/settings/apachesolr/mlt';
-    return confirm_form($form,
-      t('Are you sure you want to delete the Apache Solr content recommendation block %name?', array('%name' => $block['name'])),
-      'admin/settings/apachesolr/mlt',
-      t('The block will be deleted. This action cannot be undone.'),
-      t('Delete'), t('Cancel'));
-  }
-}
-
-function apachesolr_mlt_delete_block_form_submit($form, &$form_state) {
-  db_query('DELETE FROM {apachesolr_mlt} WHERE id = %d', $form_state['values']['block_id']['#value']);
-}
