? suggestedterms-pluggable-extractor.patch
Index: suggestedterms.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/suggestedterms/suggestedterms.install,v
retrieving revision 1.2.2.1
diff -u -p -r1.2.2.1 suggestedterms.install
--- suggestedterms.install	29 Oct 2009 16:33:10 -0000	1.2.2.1
+++ suggestedterms.install	15 Oct 2010 18:08:24 -0000
@@ -20,5 +20,24 @@ function suggestedterms_install() {
  */
 function suggestedterms_uninstall() {
   variable_del('suggestedterms_maximum_displayed');
+  variable_del('suggestedterms_method');
+}
+
+/**
+ * Migrate obsolete setting.
+ */
+function suggestedterms_update_6001() {
+  $replacements = array(
+    1 => 'popular',
+    2 => 'name',
+    3 => 'weight',
+    4 => 'recent',
+    5 => 'used',
+  );
+  $value = variable_get('suggestedterms_sort_order', 2);
+  // Only set if the previous value was not the default (which hasn't changed).
+  if ($value != 2) {
+    variable_set('suggestedterms_method', $replacements[$value]);
+  }
   variable_del('suggestedterms_sort_order');
 }
Index: suggestedterms.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/suggestedterms/suggestedterms.module,v
retrieving revision 1.2.2.7
diff -u -p -r1.2.2.7 suggestedterms.module
--- suggestedterms.module	8 Oct 2009 22:34:21 -0000	1.2.2.7
+++ suggestedterms.module	15 Oct 2010 18:08:24 -0000
@@ -4,11 +4,6 @@
 /**
 * define constants
 */
-define('SUGGESTEDTERMS_SORT_POPULAR', 0);
-define('SUGGESTEDTERMS_SORT_NAME', 1);
-define('SUGGESTEDTERMS_SORT_RECENT', 2);
-define('SUGGESTEDTERMS_SORT_WEIGHT', 3);
-define('SUGGESTEDTERMS_SORT_USED', 4);
 
 define('SUGGESTEDTERMS_DISPLAY_ALL', 1);
 define('SUGGESTEDTERMS_DISPLAY_USED', 2);
@@ -29,6 +24,54 @@ function suggestedterms_help($path, $arg
 }
 
 /**
+ * Get available term suggestion methods.
+ */
+function suggestedterms_methods($method = NULL, $setting = NULL) {
+  static $methods;
+
+  if (empty($methods)) {
+    $methods = array(
+      'popular' => array(
+        'suggestions_callback' => '_suggestedterms_build_suggestions',
+        'description' => t('Most used'),
+      ),
+      'name' => array(
+        'suggestions_callback' => '_suggestedterms_build_suggestions',
+        'description' => t('Alphabetically'),
+      ),
+      'weight' => array(
+        'suggestions_callback' => '_suggestedterms_build_suggestions',
+        'description' => t('Weight'),
+      ),
+      'recent' => array(
+        'suggestions_callback' => '_suggestedterms_build_suggestions',
+        'description' => t('Most recently added'),
+      ),
+      'used' => array(
+        'suggestions_callback' => '_suggestedterms_build_suggestions',
+        'description' => t('Most recently used'),
+      ),
+    );
+    if (module_exists('extractor')) {
+      $methods['extractor'] = array(
+        'suggestions_callback' => '_suggestedterms_suggestions_extractor',
+        'description' => t('Found in content using Extractor'),
+      );
+    }
+    // Allow other modules to alter or add methods.
+    drupal_alter('suggestedterms_methods', $methods);
+  }
+  if ($setting) {
+    $items = array();
+    foreach ($methods as $key => $settings) {
+      $items[$key] = $settings[$setting];
+    }
+    return $method ? $items[$method] : $items;
+  }
+  return $method ? $methods[$method] : $methods;
+}
+
+/**
  * Implementation of hook_perm().
  */
 function suggestedterms_perm() {
@@ -61,33 +104,33 @@ function theme_suggestedterm($name) {
 }
 
 /**
-* Creates all spans from vocabulary terms
-*
-* @return
-*   A string containing the clickable spans for the suggestedterms module.
-*/
-function _suggestedterms_build_suggestions($vid, $sort_order, $display_what) {
+ * Term filtering suggestion callback.
+ *
+ * @return
+ *   Array of suggested terms.
+ */
+function _suggestedterms_build_suggestions($node, $vid, $method, $display_what) {
   // Use left join to display all entries, inner join to diaplay only used ones.
   $query_type = ($display_what == SUGGESTEDTERMS_DISPLAY_ALL) ? " LEFT " : " INNER ";
 
   // Get total terms set by admin.
   $total_terms = variable_get('suggestedterms_maximum_displayed', 5);
 
-  // Get sort order set by admin.
-  switch ($sort_order) {
-    case SUGGESTEDTERMS_SORT_POPULAR:
+  // Get METHOD order set by admin.
+  switch ($method) {
+    case 'popular':
       $query = "SELECT t.name AS name, COUNT(t.name) AS total FROM {term_data} t $query_type JOIN {term_node} tn ON (t.tid = tn.tid) WHERE t.vid = %d GROUP BY t.name ORDER BY total desc";
       break;
 
-    case SUGGESTEDTERMS_SORT_RECENT:
+    case 'recent':
       $query = "SELECT t.name AS name FROM {term_data} t $query_type JOIN {term_node} tn ON (t.tid = nt.tid) WHERE t.vid = %d GROUP BY t.name ORDER BY t.tid desc";
       break;
 
-    case SUGGESTEDTERMS_SORT_WEIGHT:
+    case 'weight':
       $query = "SELECT t.name AS name, t.weight AS weight FROM {term_data} t $query_type JOIN {term_node} tn ON (t.tid = tn.tid) WHERE t.vid = %d GROUP BY t.name ORDER BY weight, name";
       break;
 
-    case SUGGESTEDTERMS_SORT_USED:
+    case 'used':
       $query = "SELECT DISTINCT t.name AS name FROM {term_data} t $query_type JOIN {term_node} tn ON (t.tid = tn.tid) $query_type JOIN {node} n ON (tn.nid = n.nid) WHERE t.vid = %d ORDER BY n.changed DESC, name";
       break;
 
@@ -98,9 +141,78 @@ function _suggestedterms_build_suggestio
   $query_result = ($total_terms > 0) ? db_query_range($query, $vid, 0, $total_terms) : db_query($query, $vid);
   $terms = array();
   while($record = db_fetch_object($query_result)) {
-    $terms[] = theme('suggestedterm', check_plain($record->name));
+    $terms[] = check_plain($record->name);
   }
-  return implode(', ', $terms);
+  return $terms;
+}
+
+/**
+ * Extractor suggestion callback.
+ *
+ * @return
+ *   Array of suggested terms.
+ */
+function _suggestedterms_suggestions_extractor($node, $vid, $method, $display_what) {
+  $terms = array();
+  if (module_exists('extractor')) {
+    $terms = extractor_extract(_suggestedterms_build_content($node));
+  }
+  return $terms;
+}
+
+/**
+ * Creates all spans from vocabulary terms.
+ *
+ * @return
+ *   A string containing the clickable spans for the suggestedterms module.
+ */
+function suggestedterms_suggestions_string($terms) {
+  $tags = array();
+  foreach ($terms as $term) {
+    $tags[]= theme('suggestedterm', $term);
+  }
+  return implode(', ', $tags);
+}
+/**
+ * Build node content and prepend title. Useful for generating node strings
+ * to pass for term extraction.
+ *
+ * @return
+ *   A string containing the clickable spans for the suggestedterms module.
+ */
+function _suggestedterms_build_content($node) {
+
+  // Build the node body.
+  $node = node_build_content($node, FALSE, FALSE);
+  $body = drupal_render($node->content);
+
+  return check_plain($node->title) . ' ' . $body;
+
+}
+
+/**
+ * Fetch rendered term suggestion tags.
+ *
+ * This function may be called by other modules relying on suggestedterms
+ * for a term suggestion API.
+ *
+ * @return
+ *   Array in which the first item is a method description and the second a
+ *   string with suggested terms.
+ */
+function suggestedterms_suggestions($existing, $node, $vid, $method, $display_what) {
+  $method = suggestedterms_methods($method);
+  $terms = array();
+  $callback = $method['suggestions_callback'];
+  if (function_exists($callback)) {
+    $terms = $callback($node, $vid, $method, $display_what);
+  }
+  // Remove any tags already registered.
+  $terms = array_diff($terms, $existing);
+  return array(
+    $method['description'],
+    $terms,
+  );
 }
 
 /**
@@ -114,30 +226,10 @@ function suggestedterms_form_alter(&$for
     // If multiple vocabularies, loop over each.
     foreach ($form['taxonomy']['tags'] as $vid => $thisindex) {
       // If free-tagging taxonomy is true, add new links for each free-tag textfield.
-      $sort_order = variable_get('suggestedterms_sort_order', SUGGESTEDTERMS_SORT_NAME);
-      switch ($sort_order) {
-        case SUGGESTEDTERMS_SORT_POPULAR:
-          $tag_description = t('Most popular terms');
-          break;
-
-        case SUGGESTEDTERMS_SORT_RECENT:
-          $tag_description = t('Recently added');
-          break;
-
-        case SUGGESTEDTERMS_SORT_WEIGHT:
-          $tag_description = t('Terms by Weight');
-          break;
-
-        case SUGGESTEDTERMS_SORT_USED:
-          $tag_description = t('Recently Used');
-          break;
-
-        default:
-          $tag_description = t('Terms by name');
-          break;
-      }
+      $method = variable_get('suggestedterms_method', 'name');
+      list($description, $terms) = suggestedterms_suggestions(drupal_explode_tags($thisindex['#default_value']), $form['#node'], $vid, $method, $display_what);
       // Build the suggested terms and set in description tag.
-      $form['taxonomy']['tags'][$vid]['#description'] .= "<br />\n". $tag_description . ': ' . _suggestedterms_build_suggestions($vid, $sort_order, $display_what);
+      $form['taxonomy']['tags'][$vid]['#description'] .= "<br />\n". $description . ': ' . suggestedterms_suggestions_string($terms);
     }
   }
 }
@@ -155,24 +247,18 @@ function suggestedterms_admin() {
     '#maxlength' => 2,
     '#description' => t('The maximum number of links to display in the block. Enter 0 to show all.'),
   );
-  $form['suggestedterms_sort_order'] = array(
+  $form['suggestedterms_method'] = array(
     '#type' => 'radios',
-    '#title' => t('Link sort order'),
-    '#default_value' => variable_get('suggestedterms_sort_order', SUGGESTEDTERMS_SORT_NAME),
-    '#description' => t("The sort order for the links displayed."),
-    '#options' => array(
-      SUGGESTEDTERMS_SORT_POPULAR => t('Most used'),
-      SUGGESTEDTERMS_SORT_NAME => t('Alphabetically'),
-      SUGGESTEDTERMS_SORT_WEIGHT => t('Weight'),
-      SUGGESTEDTERMS_SORT_RECENT => t('Most recently added'),
-      SUGGESTEDTERMS_SORT_USED => t('Most recently used'),
-     ),
+    '#title' => t('Suggestion method'),
+    '#default_value' => variable_get('suggestedterms_method', 'name'),
+    '#description' => t("The method used for the links displayed."),
+    '#options' => suggestedterms_methods(NULL, 'description'),
   );
   $form['suggestedterms_display_mode'] = array(
     '#type' => 'radios',
     '#title' => t('Which terms to display'),
     '#default_value' => variable_get('suggestedterms_display_mode', SUGGESTEDTERMS_DISPLAY_ALL),
-    '#description' => t("Whether to display all defined terms or only the ones previously used."),
+    '#description' => t("Whether to display all defined terms or only the ones previously used. Some suggestions methods may ignore this setting."),
     '#options' => array(
        SUGGESTEDTERMS_DISPLAY_USED => t('Previously-used terms'),
        SUGGESTEDTERMS_DISPLAY_ALL => t('All terms'),
@@ -191,7 +277,7 @@ function suggestedterms_menu() {
 
   $items['admin/content/suggestedterms'] = array(
     'title' => t('Suggested terms'),
-    'description' => t('Provide integrated suggestions of recent or popular tags from the given vocabulary.'),
+    'description' => t('Provide integrated suggestions of tags from the given vocabulary.'),
     'page callback' => 'drupal_get_form',
     'page arguments' => array('suggestedterms_admin'),
     'access arguments' => array('administer suggested terms configuration'),
