diff --git a/apachesolr_attachments.admin.inc b/apachesolr_attachments.admin.inc index dcd42a8..81a3765 100644 --- a/apachesolr_attachments.admin.inc +++ b/apachesolr_attachments.admin.inc @@ -83,6 +83,75 @@ function apachesolr_attachments_settings() { 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('
', '', $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']); @@ -244,93 +313,111 @@ function apachesolr_attachments_delete_index() { */ function apachesolr_attachments_add_documents($node, $namespace) { $documents = array(); - $hash = apachesolr_site_hash(); - // Let any module exclude this node from the index. - $build_document = TRUE; - foreach (module_implements('apachesolr_node_exclude') as $module) { - $exclude = module_invoke($module, 'apachesolr_node_exclude', $node, $namespace); - if (!empty($exclude)) { - $build_document = FALSE; - } - } - - if ($build_document) { - // 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 fid FROM {apachesolr_attachments_files} WHERE nid = %d", $node->nid); - while ($row = db_fetch_array($result)) { - $fids[$row['fid']] = $row['fid']; + if (apachesolr_attachments_get_index_mode($node) == 'seperate') { + $hash = apachesolr_site_hash(); + + // Let any module exclude this node from the index. + $build_document = TRUE; + foreach (module_implements('apachesolr_node_exclude') as $module) { + $exclude = module_invoke($module, 'apachesolr_node_exclude', $node, $namespace); + if (!empty($exclude)) { + $build_document = FALSE; + } } - $files = apachesolr_attachments_get_indexable_files($node); - - // Find deleted files. - $missing_fids = array_diff_key($fids, $files); - if ($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. - 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; - if (empty($node->language)) { - // 'und' is the language-neutral code in Drupal 7. - $document->language = 'und'; + if ($build_document) { + foreach (apachesolr_attachments_update_indexable_files($node) 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; + if (empty($node->language)) { + // 'und' is the language-neutral code in Drupal 7. + $document->language = 'und'; + } + else { + $document->language = $node->language; + } + $document->body = $file->filename .' '. 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 { - $document->language = $node->language; + // Shortened project name because the watchdog limits type to 16 characters. + watchdog('ApacheSolrAttach', 'Could not extract any indexable text from %filepath', array('%filepath' => $file->filepath), WATCHDOG_WARNING); } - $document->body = $file->filename .' '. apachesolr_clean_text($file->description) .' '. $text; + } + } + } + return $documents; +} + +/** + * 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) { - $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)); + // 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. - apachesolr_add_taxonomy_to_document($document, $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']; + } - // 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); + $files = apachesolr_attachments_get_indexable_files($node); - $documents[] = $document; - } - else { - // Shortened project name because the watchdog limits type to 16 characters. - watchdog('ApacheSolrAttach', 'Could not extract any indexable text from %filepath', array('%filepath' => $file->filepath), WATCHDOG_WARNING); - } - } + // Find deleted files. + $missing_fids = array_diff_key($fids, $files); + if ($missing_fids) { + db_query("UPDATE {apachesolr_attachments_files} SET removed = 1 WHERE fid IN (". db_placeholders($missing_fids) .")", $missing_fids); } - return $documents; + $new_files = array_diff_key($files, $fids); + // Add new files. + foreach ($new_files as $file) { + db_query("INSERT INTO {apachesolr_attachments_files} (fid, nid, removed, sha1) VALUES (%d, %d, 0, '')", $file->fid, $node->nid); + } + + return $files; } + /** * Return all non-excluded file attachments for a particular node */ @@ -414,6 +501,9 @@ function apachesolr_attachments_get_cck_file_fields() { * @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. diff --git a/apachesolr_attachments.install b/apachesolr_attachments.install index 876ce37..83e7940 100644 --- a/apachesolr_attachments.install +++ b/apachesolr_attachments.install @@ -27,6 +27,7 @@ function apachesolr_attachments_uninstall() { variable_del('apachesolr_attachements_cron_try'); apachesolr_clear_last_index('apachesolr_attachments'); drupal_uninstall_schema('apachesolr_attachments'); + db_query("DELETE FROM {variable} WHERE name LIKE 'apachesolr_attachments_content_type_indexing_%%'"); } /** diff --git a/apachesolr_attachments.module b/apachesolr_attachments.module index 4a21357..fed8f3c 100644 --- a/apachesolr_attachments.module +++ b/apachesolr_attachments.module @@ -20,6 +20,20 @@ function apachesolr_attachments_menu() { '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', @@ -89,6 +103,19 @@ function apachesolr_attachments_search($op = 'search', $keys = NULL) { } /** + * 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) { @@ -154,6 +181,34 @@ function apachesolr_attachments_nodeapi($node, $op) { // 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); } + else if ($op == '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 $file) { + $text .= "\n " . apachesolr_attachments_get_attachment_text($file); + } + + return $text; + } + } +} + +/** + * 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; } /**