### Eclipse Workspace Patch 1.0
#P solr_attachements
Index: apachesolr_attachments.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr_attachments/apachesolr_attachments.admin.inc,v
retrieving revision 1.4.2.6
diff -u -r1.4.2.6 apachesolr_attachments.admin.inc
--- apachesolr_attachments.admin.inc	22 Jun 2010 16:02:23 -0000	1.4.2.6
+++ apachesolr_attachments.admin.inc	14 Jul 2010 10:09:58 -0000
@@ -17,7 +17,7 @@
 
 /**
  * Displays the Attachment Settings Form.
-*/
+ */
 function apachesolr_attachments_settings() {
   $default = implode(' ', apachesolr_attachments_default_excluded());
   $form['apachesolr_attachment_excluded_extensions'] = array(
@@ -84,6 +84,73 @@
   return $form;
 }
 
+/**
+ * Form callback for content type settings.
+ */
+function apachesolr_attachments_content_type_settings() {
+  list($excluded_types) = _apachesolr_exclude_types('apachesolr_attachments');
+  $types = array_diff_key(node_get_types('names'), $excluded_types);
+
+  foreach ($types as $key => $name) {
+    $form['content_type-settings']['apachesolr_attachments_content_type_indexing_' . $key] = array(
+      '#type' => 'radios',
+      '#title' => t('@type', array('@type' => $name)),
+      '#default_value' => variable_get('apachesolr_attachments_content_type_indexing_' . $key, 'seperate'),
+      '#options' => array(
+        'seperate' => t('Attachments as separate entities'),
+        'parent' => t('Attachments as part of parent node'),
+        'none' => t("Don't index attachments"),
+      ),
+    );
+  }
+
+  $form = system_settings_form($form);
+  $form['#theme'] = 'apachesolr_attachments_content_type_settings'; // reset form theme.
+  return $form;
+}
+
+/**
+ * Theme callback for apachesolr_attachments content type settings.
+ *
+ * This groups radio elements into a table that should be more manageble for
+ * larger numbers of content types.
+ *
+ * @group themeable
+ */
+function theme_apachesolr_attachments_content_type_settings($form) {
+
+  $headers = array();
+  $rows = array();
+  foreach (element_children($form['content_type-settings']) as $index) {
+    $element = &$form['content_type-settings'][$index];
+    $row = array();
+
+    if (empty($headers)) {
+      $headers[] = t('Content type');
+      foreach (element_children($element) as $sub_index) {
+        $headers[] = $element[$sub_index]['#title'];
+      }
+    }
+
+    foreach (element_children($element) as $sub_index) {
+      unset($element[$sub_index]['#title']);
+      $row[] = drupal_render($element[$sub_index]);
+    }
+    // Toss actual rendering.
+    $label = drupal_render($element);
+    // Hack out radios raper that's not very useful now.
+    $label = str_replace('<div class="form-radios"></div>', '', $label);
+    array_unshift($row, $label);
+    $rows[] = $row;
+  }
+
+  $output = theme('table', $headers, $rows);
+
+  $output .= drupal_render($form);
+
+  return $output;
+}
+
 function apachesolr_attachments_settings_validate($form, &$form_state) {
   if ($form_state['values']['apachesolr_attachment_extract_using'] == 'tika') {
     $path = realpath($form_state['values']['apachesolr_attachments_tika_path']);
@@ -224,105 +291,140 @@
  */
 function apachesolr_attachments_add_documents(&$documents, $nid, $namespace = 'apachesolr_attachments') {
   $node = node_load($nid, NULL, TRUE);
-  if (!empty($node->nid)) {
+  $index_mode = apachesolr_attachments_get_index_mode($node);
+  if (!empty($node->nid) && $index_mode == 'seperate') {
 
     $hash = apachesolr_site_hash();
 
-    // Since there is no notification for an attachment being unassociated with a
-    // node (but that action will trigger it to be indexed again), we check for
-    // fids that were added before but no longer present on this node.
+    $files = apachesolr_attachments_update_indexable_files($node);
 
-    $fids = array();
-    $result = db_query("SELECT fid FROM {apachesolr_attachments_files} WHERE nid = %d", $node->nid);
-    while ($row = db_fetch_array($result)) {
-      $fids[$row['fid']] = $row['fid'];
+    foreach ($files as $type => $list) {
+      foreach ($list as $file) {
+        $text = apachesolr_attachments_get_attachment_text($file);
+
+        if ($text) {
+          $document = new Apache_Solr_Document();
+          // A single file might be attached to multiple nodes.
+          $document->id = apachesolr_document_id($file->fid .'-'. $node->nid, 'file');
+          $document->url = $file->filepath;
+          $document->path = $file->filepath;
+          $document->hash = $hash;
+          $document->entity = 'file';
+          $document->site = url(NULL, array('absolute' => TRUE));
+          $document->nid = $node->nid;
+          $document->title = $file->filename;
+          $document->created = apachesolr_date_iso($file->timestamp);
+          $document->changed = $document->created;
+          $document->status = $node->status;
+          $document->sticky = $node->sticky;
+          $document->promote = $node->promote;
+          $document->uid = $node->uid;
+          $document->name = $node->name;
+          $document->body = apachesolr_clean_text($file->description) .' '. $text;
+
+          $document->ss_filemime = $file->filemime;
+          $document->ss_file_node_title = apachesolr_clean_text($node->title);
+          $document->ss_file_node_url = url('node/' . $node->nid, array('absolute' => TRUE));
+          $document->ss_file_type = $type;
+
+          apachesolr_add_taxonomy_to_document($document, $node);
+
+          // Let modules add to the document.
+          foreach (module_implements('apachesolr_update_index') as $module) {
+            $function = $module .'_apachesolr_update_index';
+            $function($document, $node, $namespace);
+          }
+          drupal_alter('apachesolr_attachment_index', $document, $node, $file, $namespace);
+
+          $documents[] = $document;
+        }
+        else {
+          watchdog('Apache Solr Attachments', t('Could not extract any indexable text from %filepath'), array('%filepath' => $file->filepath), WATCHDOG_WARNING);
+        }
+      }
     }
+  }
+}
+
+/**
+ * Builds an updated list of indexable files and updates related caches.
+ *
+ * @param $node
+ * A Drupal node object associated with the files.
+ * @return
+ * A list of indexable file objects.
+ */
+function apachesolr_attachments_update_indexable_files($node) {
 
-    $files = apachesolr_attachments_get_indexable_files($node);
+  // Since there is no notification for an attachment being unassociated with a
+  // node (but that action will trigger it to be indexed again), we check for
+  // fids that were added before but no longer present on this node.
 
+  $fids = array();
+  $result = db_query("SELECT file_type, fid FROM {apachesolr_attachments_files} WHERE nid = %d", $node->nid);
+  while ($row = db_fetch_array($result)) {
+    $fids[$row['file_type']][$row['fid']] = $row['fid'];
+  }
+
+  $files = apachesolr_attachments_get_indexable_files($node);
+
+  foreach ($files as $module => $list) {
+    $fids[$module] = is_array($fids[$module]) ? $fids[$module] : array();
     // Find deleted files.
-    $missing_fids = array_diff_key($fids, $files);
+    $missing_fids = array_diff_key($fids[$module], $list);
     if ($missing_fids) {
-      db_query("UPDATE {apachesolr_attachments_files} SET removed = 1 WHERE fid IN (". db_placeholders($missing_fids) .")", $missing_fids);
+      db_query("UPDATE {apachesolr_attachments_files} SET removed = 1 WHERE fid IN (" . db_placeholders($missing_fids) . ")", $missing_fids);
     }
-    $new_files = array_diff_key($files, $fids);
+
     // Add new files.
+    $new_files = array_diff_key($list, $fids[$module]);
     foreach ($new_files as $file) {
-      db_query("INSERT INTO {apachesolr_attachments_files} (fid, nid, removed, sha1) VALUES (%d, %d, 0, '')", $file->fid, $node->nid);
-    }
-    foreach ($files as $file) {
-      $text = apachesolr_attachments_get_attachment_text($file);
-
-      if ($text) {
-        $document = new Apache_Solr_Document();
-        // A single file might be attached to multiple nodes.
-        $document->id = apachesolr_document_id($file->fid .'-'. $node->nid, 'file');
-        $document->url = file_create_url($file->filepath);
-        $document->path = $file->filepath;
-        $document->hash = $hash;
-        $document->entity = 'file';
-        $document->site = url(NULL, array('absolute' => TRUE));
-        $document->nid = $node->nid;
-        $document->title = $file->filename;
-        $document->created = apachesolr_date_iso($file->timestamp);
-        $document->changed = $document->created;
-        $document->status = $node->status;
-        $document->sticky = $node->sticky;
-        $document->promote = $node->promote;
-        $document->uid = $node->uid;
-        $document->name = $node->name;
-        $document->body = apachesolr_clean_text($file->description) .' '. $text;
-
-        $document->ss_filemime = $file->filemime;
-        $document->ss_file_node_title = apachesolr_clean_text($node->title);
-        $document->ss_file_node_url = url('node/' . $node->nid, array('absolute' => TRUE));
-
-        apachesolr_add_taxonomy_to_document($document, $node);
-
-        // Let modules add to the document.
-        foreach (module_implements('apachesolr_update_index') as $module) {
-          $function = $module .'_apachesolr_update_index';
-          $function($document, $node, $namespace);
-        }
-        drupal_alter('apachesolr_attachment_index', $document, $node, $file, $namespace);
-
-        $documents[] = $document;
-      }
-      else {
-        watchdog('Apache Solr Attachments', 'Could not extract any indexable text from %filepath', array('%filepath' => $file->filepath), WATCHDOG_WARNING);
-      }
+      db_query("INSERT INTO {apachesolr_attachments_files} (fid, file_type, nid, removed, sha1) VALUES (%d, '%s', %d, 0, '')", $file->fid, $module, $node->nid);
     }
   }
+
+  return $files;
 }
 
 /**
  * Return all non-excluded file attachments for a particular node
  */
 function apachesolr_attachments_get_indexable_files($node) {
-  $files = array();
+  $files['drupal'] = array();
 
   if(!empty($node->files)) {
-    $files = $node->files;
+    $files['drupal'] = $node->files;
   }
 
   $fields = apachesolr_attachments_get_cck_file_fields();
   foreach ($fields as $field) {
     if(!empty($node->$field)) {
-      $files = array_merge($files, $node->$field);
+      $files['drupal'] = array_merge($files['drupal'], $node->$field);
     }
   }
+
+  // Allow other modules to attach files to be indexed.
+  foreach (module_implements('apachesolr_attachments_files') as $module) {
+    $files[$module] = module_invoke($module, 'apachesolr_attachments_files', $node);
+  }
+
   $file_list = array();
-  foreach ($files as $file) {
-    // Some are arrays others are objects, treat them all as objects
-    $file = (object) $file;
-    // Some filefield-enabled nodes show up with an emtpy file array.
-    if (!empty($file->fid) && apachesolr_attachments_allowed_mime($file->filemime)) {
-      if (isset($file->data['description']) && !isset($file->description)) {
-        $file->description = $file->data['description'];
+  foreach ($files as $module => $list) {
+    foreach ($list as $file) {
+      // Some are arrays others are objects, treat them all as objects
+      $file = (object) $file;
+
+      // Some filefield-enabled nodes show up with an emtpy file array.
+      if (!empty($file->fid) && apachesolr_attachments_allowed_mime($file->filemime)) {
+        if (isset($file->data['description']) && !isset($file->description)) {
+          $file->description = $file->data['description'];
+        }
+
+        $file_list[$module][$file->fid] = $file;
       }
-      $file_list[$file->fid] = $file;
     }
   }
+
   return $file_list;
 }
 
@@ -378,6 +480,9 @@
  * @throws Exception
  */
 function apachesolr_attachments_get_attachment_text($file) {
+  // We need the apachesolr_clean_text function so include this file:
+  module_load_include('inc', 'apachesolr', 'apachesolr.index');
+
   // Any down-side to using realpath()?
   $filepath = realpath($file->filepath);
   // Check that we have a valid filepath.
@@ -483,4 +588,3 @@
   $response = $solr->makeServletRequest(EXTRACTING_SERVLET, $params, 'POST', $headers, $data);
   return array($response->extracted, $response->extracted_metadata);
 }
-
Index: apachesolr_attachments.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr_attachments/apachesolr_attachments.install,v
retrieving revision 1.1.4.1
diff -u -r1.1.4.1 apachesolr_attachments.install
--- apachesolr_attachments.install	28 Dec 2009 00:26:59 -0000	1.1.4.1
+++ apachesolr_attachments.install	14 Jul 2010 10:09:58 -0000
@@ -6,7 +6,7 @@
  */
 function apachesolr_attachments_install() {
   drupal_install_schema('apachesolr_attachments');
-} 
+}
 
 /**
  * Implementation of hook_uninstall().
@@ -20,6 +20,7 @@
   variable_del('apachesolr_attachment_excluded_mime');
   apachesolr_clear_last_index('apachesolr_attachments');
   drupal_uninstall_schema('apachesolr_attachments');
+  db_query("DELETE FROM {variable} WHERE name LIKE 'apachesolr_attachments_content_type_indexing_%%'");
 }
 
 /**
@@ -37,7 +38,7 @@
       exec($java .' -version > '. $temp .' 2>&1');
       $stderror = file_get_contents($temp);
       $found = preg_match('/Runtime Environment/', $stderror);
-  
+
       if (!$found) {
         $requirements['apachesolr_attachments_java']  = array(
           'title' => $t('Java executable not found'),
@@ -63,6 +64,12 @@
         'type' => 'int',
         'unsigned' => TRUE,
         'not null' => TRUE),
+      'file_type' => array(
+        'description' => 'File type used to diferentiate different backends.',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => ''),
       'nid' => array(
         'description' => 'The {node}.nid where the file is attached.',
         'type' => 'int',
@@ -90,7 +97,7 @@
       'nid' => array('nid'),
       'removed' => array('removed'),
       ),
-    'primary key' => array('fid'),
+    'primary key' => array('fid', 'file_type'),
     );
 
   return $schema;
@@ -130,3 +137,24 @@
   apachesolr_clear_last_index('apachesolr_attachments');
   return $ret;
 }
+
+/**
+ * Add file type key for supporting multiple file backends.
+ */
+function apachesolr_attachments_update_6002() {
+  $ret = array();
+
+  $schema = array(
+    'description' => 'File type used to diferentiate different backends.',
+    'type' => 'varchar',
+    'length' => 255,
+    'not null' => TRUE,
+    'default' => '',
+    'initial' => 'drupal',
+  );
+  db_add_field($ret, 'apachesolr_attachments_files', 'file_type', $schema);
+  db_drop_primary_key($ret, 'apachesolr_attachments_files');
+  db_add_primary_key($ret, 'apachesolr_attachments_files', array('fid', 'file_type'));
+
+  return $ret;
+}
Index: apachesolr_attachments.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr_attachments/apachesolr_attachments.module,v
retrieving revision 1.1.4.2
diff -u -r1.1.4.2 apachesolr_attachments.module
--- apachesolr_attachments.module	3 Feb 2010 18:44:02 -0000	1.1.4.2
+++ apachesolr_attachments.module	14 Jul 2010 10:09:58 -0000
@@ -21,6 +21,20 @@
     'file' => 'apachesolr_attachments.admin.inc',
     'type' => MENU_LOCAL_TASK,
   );
+  $items['admin/settings/apachesolr/attachments/general'] = array(
+    'title' => 'General',
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+  );
+  $items['admin/settings/apachesolr/attachments/content_type'] = array(
+    'title' => 'Content type',
+    'description' => 'Administer Apache Solr Attachments per content settings.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('apachesolr_attachments_content_type_settings'),
+    'access arguments' => array('administer search'),
+    'file' => 'apachesolr_attachments.admin.inc',
+    'type' => MENU_LOCAL_TASK,
+    'weight' => 1,
+  );
   $items['admin/settings/apachesolr/attachments/confirm/reindex'] = array(
     'title' => 'Reindex all files',
     'page callback' => 'drupal_get_form',
@@ -90,6 +104,19 @@
 }
 
 /**
+ * Implementation of hook_theme().
+ */
+function apachesolr_attachments_theme() {
+  return array(
+    // Point this to our admin file for the theme function.
+    'apachesolr_attachments_content_type_settings' => array(
+      'arguments' => array('form' => NULL),
+      'file' => 'apachesolr_attachments.admin.inc',
+    ),
+  );
+}
+
+/**
  * Implementation of hook_apachesolr_types_exclude().
  */
 function apachesolr_attachments_apachesolr_types_exclude($namespace) {
@@ -138,10 +165,40 @@
       // Mark attachments for later re-deletion in case the query fails.
       db_query("UPDATE {apachesolr_attachments_files} SET removed = 1 WHERE nid = %d", $node->nid);
       break;
+    case 'update index':
+      $index_mode = apachesolr_attachments_get_index_mode($node);
+      if ($index_mode == 'parent') {
+
+        module_load_include('inc', 'apachesolr_attachments', 'apachesolr_attachments.admin');
+
+        $text = '';
+        foreach (apachesolr_attachments_update_indexable_files($node) as $type => $list) {
+          foreach ($list as $file) {
+            $text .= "\n " . apachesolr_attachments_get_attachment_text($file);
+          }
+        }
+
+        return $text;
+      }
+      break;
   }
 }
 
 /**
+ * Get the indexing mode for the attachments of a given node.
+ *
+ * @param $node
+ * A node object.
+ * @return
+ * Index mode
+ */
+function apachesolr_attachments_get_index_mode($node) {
+  $index_mode = variable_get('apachesolr_attachments_content_type_indexing_' . $node->type, 'seperate');
+  drupal_alter('apachesolr_attachments_index_mode', $index_mode, $node);
+  return $index_mode;
+}
+
+/**
  * Implementation of hook_cron().
  *
  * Delete all removed attachments from the Solr store.
@@ -194,7 +251,7 @@
   foreach ($results as &$item) {
     if (isset($item['node']->ss_filemime)) {
       $nid = $item['node']->nid;
-      $item['link'] = file_create_url($item['node']->path);
+      $item['link'] = apachesolr_attachments_create_url($item['node']);
       $node_link = t('<em>attached to:</em> !node_link', array('!node_link' => l($item['node']->ss_file_node_title, 'node/'. $nid)));
       $icon = theme('filefield_icon', array('filemime' => $item['node']->ss_filemime));
       $file_type = t('!icon @filemime', array('@filemime' => $item['node']->ss_filemime, '!icon' => $icon));
@@ -206,6 +263,23 @@
 }
 
 /**
+ * Wrap Drupal's file_create_url and provide modules the ability to provide alternative implementations.
+ *
+ * @param $node
+ * The document from solr's results.
+ * @return A url linking to the file.
+ */
+function apachesolr_attachments_create_url($node) {
+  if (isset($node->ss_file_type) && module_hook($node->ss_file_type, 'apachesolr_attachments_url')) {
+    $url = module_invoke('apachesolr_attachments_url', $node);
+  }
+  else {
+    $url = file_create_url($node->path);
+  }
+  return $url;
+}
+
+/**
  * For a particular node id, remove all file attachments from the solr index.
  */
 function apachesolr_attachments_remove_attachments_from_index($nid) {
@@ -218,4 +292,3 @@
     watchdog('Apache Solr Attachments', nl2br(check_plain($e->getMessage())), NULL, WATCHDOG_ERROR);
   }
 }
-
Index: .buildpath
===================================================================
RCS file: .buildpath
diff -N .buildpath
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ .buildpath	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<buildpath>
+	<buildpathentry kind="src" path=""/>
+	<buildpathentry kind="con" path="org.eclipse.php.core.LANGUAGE"/>
+</buildpath>
Index: .project
===================================================================
RCS file: .project
diff -N .project
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ .project	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>solr_attachements</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.wst.validation.validationbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.dltk.core.scriptbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.php.core.PHPNature</nature>
+	</natures>
+</projectDescription>
