diff --git a/apachesolr_attachments.admin.inc b/apachesolr_attachments.admin.inc index 7d6fda3..1b00223 100644 --- a/apachesolr_attachments.admin.inc +++ b/apachesolr_attachments.admin.inc @@ -90,6 +90,66 @@ function apachesolr_attachments_settings($form) { } /** + * Form callback for content type settings. + */ +function apachesolr_attachments_content_type_settings() { + + $excluded_types = apachesolr_get_excluded_types('apachesolr_attachments'); + $types = array_diff_key(node_type_get_types(), $excluded_types); + $form = array(); + + foreach ($types as $key => $type) { + $form['apachesolr_attachments_content_type_indexing_' . $key] = array( + '#type' => 'select', + '#title' => t('@type', array('@type' => $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['#theme'] = 'apachesolr_attachments_content_type_settings'; // reset form theme. + return system_settings_form($form); +} + +function theme_apachesolr_attachments_content_type_settings($variables) { + $form = $variables['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; +} +/** * Form validation for the Apache Solr Attachments settings form. * * @see apachesolr_attachments_settings() diff --git a/apachesolr_attachments.index.inc b/apachesolr_attachments.index.inc index d2223a3..8b6b853 100644 --- a/apachesolr_attachments.index.inc +++ b/apachesolr_attachments.index.inc @@ -14,123 +14,125 @@ */ 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 = :nid", array(':nid' => $node->nid)); - foreach ($result as $row) { - $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); + 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 = :nid", array(':nid' => $node->nid)); + foreach ($result as $row) { + $fids[$row->fid] = $row->fid; + } - // Find deleted files. - $missing_fids = array_diff_key($fids, $files); - if ($missing_fids) { - db_update('apachesolr_attachments_files')->fields(array('removed' => 1))->condition('fid', $missing_fids, 'IN')->execute(); - } - $new_files = array_diff_key($files, $fids); + $files = apachesolr_attachments_get_indexable_files($node); - // Add new files. - foreach ($new_files as $file) { - db_insert('apachesolr_attachments_files')->fields(array( - 'fid' => $file['fid'], - 'nid' => $node->nid, - 'removed' => 0, - 'hash' => '', - ))->execute(); - } + // Find deleted files. + $missing_fids = array_diff_key($fids, $files); + if ($missing_fids) { + db_update('apachesolr_attachments_files')->fields(array('removed' => 1))->condition('fid', $missing_fids, 'IN')->execute(); + } + $new_files = array_diff_key($files, $fids); + + // Add new files. + foreach ($new_files as $file) { + db_insert('apachesolr_attachments_files')->fields(array( + 'fid' => $file['fid'], + 'nid' => $node->nid, + 'removed' => 0, + 'hash' => '', + ))->execute(); + } - foreach ($files as $file) { - $text = apachesolr_attachments_get_attachment_text($file); - if ($text) { - $document = new ApacheSolrDocument(); - // A single file might be attached to multiple nodes. - $document->id = apachesolr_document_id($file['fid'] . '-' . $node->nid, 'file'); - $document->site = url(NULL, array('absolute' => TRUE)); - $document->hash = $hash; - $document->entity_type = 'file'; - $document->entity_id = $file['fid']; - $document->bundle = $node->type; - $document->bundle_name = node_type_get_name($node); - $document->label = $file['filename']; - $document->is_nid = $node->nid; - $document->url = file_create_url($file['uri']); - $document->path = file_stream_wrapper_get_instance_by_uri($file['uri'])->getDirectoryPath() . '/' . file_uri_target($file['uri']); - - $document->content = $file['filename'] . ' ' . apachesolr_clean_text($file['description']) . ' ' . $text; - - $document->ss_name = $node->name; - // We want the name to ale be searchable for keywords. - $document->tos_name = $node->name; - - // Everything else uses dynamic fields - $document->is_uid = $node->uid; - $document->bs_status = $node->status; - $document->bs_sticky = $node->sticky; - $document->bs_promote = $node->promote; - $document->is_tnid = $node->tnid; - $document->bs_translate = $node->translate; - if (empty($node->language)) { - // 'und' is the language-neutral code in Drupal 7. - $document->ss_language = LANGUAGE_NONE; - } - else { - $document->ss_language = $node->language; - } - $document->ds_created = apachesolr_date_iso($file['timestamp']); - $document->ds_changed = $document->ds_created; - - // apachesolr_attachments-specific fields. - $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)); - - // Add taxonomy to document. - $indexed_fields = apachesolr_entity_fields('node'); - foreach ($indexed_fields as $index_key => $field_info) { - if ($field_info['field']['type'] == 'taxonomy_term_reference') { // Add only taxonomy. - $field_name = $field_info['field']['field_name']; - // See if the node has fields that can be indexed - if (isset($node->{$field_name})) { - // Got a field. - $function = $field_info['indexing_callback']; - if ($function && function_exists($function)) { - // NOTE: This function should always return an array. One - // node field may be indexed to multiple Solr fields. - $fields = $function($node, $field_name, $index_key, $field_info); - foreach ($fields as $field) { - // It's fine to use this method also for single value fields. - $document->setMultiValue($field['key'], $field['value']); + foreach ($files as $file) { + $text = apachesolr_attachments_get_attachment_text($file); + if ($text) { + $document = new ApacheSolrDocument(); + // A single file might be attached to multiple nodes. + $document->id = apachesolr_document_id($file['fid'] . '-' . $node->nid, 'file'); + $document->site = url(NULL, array('absolute' => TRUE)); + $document->hash = $hash; + $document->entity_type = 'file'; + $document->entity_id = $file['fid']; + $document->bundle = $node->type; + $document->bundle_name = node_type_get_name($node); + $document->label = $file['filename']; + $document->is_nid = $node->nid; + $document->url = file_create_url($file['uri']); + $document->path = file_stream_wrapper_get_instance_by_uri($file['uri'])->getDirectoryPath() . '/' . file_uri_target($file['uri']); + + $document->content = $file['filename'] . ' ' . apachesolr_clean_text($file['description']) . ' ' . $text; + + $document->ss_name = $node->name; + // We want the name to ale be searchable for keywords. + $document->tos_name = $node->name; + + // Everything else uses dynamic fields + $document->is_uid = $node->uid; + $document->bs_status = $node->status; + $document->bs_sticky = $node->sticky; + $document->bs_promote = $node->promote; + $document->is_tnid = $node->tnid; + $document->bs_translate = $node->translate; + if (empty($node->language)) { + // 'und' is the language-neutral code in Drupal 7. + $document->ss_language = LANGUAGE_NONE; + } + else { + $document->ss_language = $node->language; + } + $document->ds_created = apachesolr_date_iso($file['timestamp']); + $document->ds_changed = $document->ds_created; + + // apachesolr_attachments-specific fields. + $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)); + + // Add taxonomy to document. + $indexed_fields = apachesolr_entity_fields('node'); + foreach ($indexed_fields as $index_key => $field_info) { + if ($field_info['field']['type'] == 'taxonomy_term_reference') { // Add only taxonomy. + $field_name = $field_info['field']['field_name']; + // See if the node has fields that can be indexed + if (isset($node->{$field_name})) { + // Got a field. + $function = $field_info['indexing_callback']; + if ($function && function_exists($function)) { + // NOTE: This function should always return an array. One + // node field may be indexed to multiple Solr fields. + $fields = $function($node, $field_name, $index_key, $field_info); + foreach ($fields as $field) { + // It's fine to use this method also for single value fields. + $document->setMultiValue($field['key'], $field['value']); + } } } } } - } - // 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_attachments_index', $document, $node, $file, $namespace); + // 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_attachments_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); + $documents[] = $document; + } + else { + watchdog('Apache Solr Attachments', 'Could not extract any indexable text from %filepath', array('%filepath' => $file['filepath']), WATCHDOG_WARNING); + } } } } @@ -138,6 +140,49 @@ function apachesolr_attachments_add_documents($node, $namespace) { } /** + * 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) { + + // 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_select('apachesolr_attachments_files', 'files')->fields('files', array('fid'))->condition('nid', $node->nid)->execute(); + foreach($result as $row) { + $fids[$row->fid] = $row->fid; + } + + $files = apachesolr_attachments_get_indexable_files($node); + + // Find deleted files. + $missing_fids = array_diff_key($fids, $files); + if ($missing_fids) { + db_update('apachesolr_attachments_files')->fields(array('removed' => 1))->condition('fid', $missing_fids, 'IN')->execute(); + } + $new_files = array_diff_key($files, $fids); + // Add new files. + foreach ($new_files as $fid => $file) { + db_insert('apachesolr_attachments_files') + ->fields(array( + 'fid' => $fid, + 'nid' => $node->nid, + 'removed' => 0, + 'hash' => '', + )) + ->execute(); + } + + return $files; +} + +/** * Return all non-excluded file attachments for a particular node */ function apachesolr_attachments_get_indexable_files($node) { diff --git a/apachesolr_attachments.install b/apachesolr_attachments.install index a236eba..1c944d8 100644 --- a/apachesolr_attachments.install +++ b/apachesolr_attachments.install @@ -35,6 +35,9 @@ function apachesolr_attachments_uninstall() { unset($active[$index]); variable_set('search_active_modules', $active); } + db_delete('variable') + ->condition('name', db_like('apachesolr_attachments_content_type_indexing_') , '%', 'LIKE') + ->execute(); } /** diff --git a/apachesolr_attachments.module b/apachesolr_attachments.module index 58644ac..f7bb47c 100644 --- a/apachesolr_attachments.module +++ b/apachesolr_attachments.module @@ -44,6 +44,20 @@ function apachesolr_attachments_menu() { 'file' => 'apachesolr_attachments.admin.inc', 'type' => MENU_CALLBACK, ); + $items['admin/config/search/apachesolr/attachments/general'] = array( + 'title' => 'General', + 'type' => MENU_DEFAULT_LOCAL_TASK, + ); + $items['admin/config/search/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, + ); return $items; } @@ -156,10 +170,32 @@ function apachesolr_attachments_update_index() { // ultimately apachesolr_attachments_add_documents(). $success = apachesolr_index_nodes($rows, 'apachesolr_attachments'); $num_tried += $cron_try; + } while ($success && ($num_tried < $cron_limit) && (REQUEST_TIME - $start < $cron_time_limit)); } } + +/** + * Implements hook_apachesolr_update_index() + */ +function apachesolr_attachments_apachesolr_update_index(&$document, $node) { + + $index_mode = apachesolr_attachments_get_index_mode($node); + if ($index_mode == 'parent') { + + module_load_include('inc', 'apachesolr_attachments', 'apachesolr_attachments.index'); + + $text = ''; + foreach (apachesolr_attachments_update_indexable_files($node) as $file) { + $text .= "\n " . apachesolr_attachments_get_attachment_text($file); + } + + $document->content .= $text; + } + +} + /** * Implements hook_node_update(). * @@ -295,6 +331,10 @@ function apachesolr_attachments_theme() { 'apachesolr_search_snippets__file' => array( 'variables' => array('doc' => NULL, 'snippets' => array()), ), +/* 'apachesolr_attachments_content_type_settings' => array( + 'render element' => 'form', + 'file' => 'apachesolr_attachments.admin.inc', + ),*/ ); } @@ -323,3 +363,17 @@ function apachesolr_attachments_default_excluded() { $default = array('aif', 'art', 'avi', 'bmp', 'gif', 'ico', 'jpg', 'mov', 'mp3', 'mp4', 'mpg', 'oga', 'ogv', 'png', 'psd', 'ra', 'ram', 'rgb', 'tif'); return $default; } + +/** + * 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; +}