#84207: full-text search for API. From: Damien Tournoud --- api_solr/api_solr.info | 7 ++ api_solr/api_solr.install | 13 +++ api_solr/api_solr.module | 184 +++++++++++++++++++++++++++++++++++++++++++++ parser.inc | 8 ++ 4 files changed, 212 insertions(+), 0 deletions(-) create mode 100644 api_solr/api_solr.info create mode 100644 api_solr/api_solr.install create mode 100644 api_solr/api_solr.module diff --git api_solr/api_solr.info api_solr/api_solr.info new file mode 100644 index 0000000..9931f50 --- /dev/null +++ api_solr/api_solr.info @@ -0,0 +1,7 @@ +; $Id$ +name = API Solr +description = Apache Solr integration for the API module. +package = Development +core = 6.x +dependencies[] = api +dependencies[] = apachesolr diff --git api_solr/api_solr.install api_solr/api_solr.install new file mode 100644 index 0000000..167ad81 --- /dev/null +++ api_solr/api_solr.install @@ -0,0 +1,13 @@ +did; + } + + db_query("UPDATE {apachesolr_search_node} SET changed = %d WHERE nid IN (" . db_placeholders($nids, 'int') . ")", $args); +} + +/** + * Implementation of hook_apachesolr_update_index(). + */ +function api_solr_apachesolr_update_index(&$document, $node) { + if ($node->type == 'api') { + // We are indexing a api pseudo-node, identify the corresponding docblock. + $result = db_fetch_array(db_query('SELECT object_name, object_type, branch_name FROM {api_documentation} WHERE did = %d', $node->nid)); + if (!$result) { + // Bail out. + return; + } + + if ($result['branch_name'] == 'php') { + // Ignore PHP function reference. + $document = NULL; + return; + } + + // Load the doc block. + $doc_block = api_object_load($result['object_name'], $result['object_type'], $result['branch_name']); + + // Inject doc block data into the Apachesolr document. + $document->title = $doc_block->title; + $document->body = apachesolr_clean_text($doc_block->documentation); + $document->ss_api_object_name = $doc_block->object_name; + $document->ss_api_object_type = $doc_block->object_type; + $document->ss_api_branch_name = $doc_block->branch_name; + $document->ss_api_file_name = $doc_block->file_name; + + // Object-type specific handling. + switch ($result['object_type']) { + case 'function': + $document->title = $doc_block->signature; + $document->body .= ' ' . apachesolr_clean_text($doc_block->parameters); + break; + case 'file': + $document->title = $doc_block->file_name; + break; + } + } +} + +/** + * Implementation of hook_apachesolr_field_name_map_alter(). + * + * Define the name of the api_solr custom fields for convinience. + */ +function api_solr_apachesolr_field_name_map_alter(&$map) { + $map += array( + 'ss_api_object_name' => t('API: Object name'), + 'ss_api_object_type' => t('API: Object type'), + 'ss_api_branch_name' => t('API: Branch name'), + 'ss_api_file_name' => t('API: File name'), + ); +} + +/** + * Implementation of hook_apachesolr_facets(). + * + * Expose API-specific facets. + */ +function api_solr_apachesolr_facets() { + $facets['ss_api_object_type'] = array( + 'info' => t('API: Filter by object type'), + 'facet_field' => 'ss_api_object_type', + ); + $facets['ss_api_branch_name'] = array( + 'info' => t('API: Filter by branch name'), + 'facet_field' => 'ss_api_branch_name', + ); + $facets['ss_api_file_name'] = array( + 'info' => t('API: Filter by file name'), + 'facet_field' => 'ss_api_file_name', + ); + + return $facets; +} + +/** + * Implementation of hook_block(). + */ +function api_solr_block($op = 'list', $delta = 0, $edit = array()) { + + switch ($op) { + case 'list': + $enabled_facets = apachesolr_get_enabled_facets('api_solr'); + $facets = api_solr_apachesolr_facets(); + // Add the blocks + $blocks = array(); + foreach ($enabled_facets as $delta => $facet_field) { + if (isset($facets[$delta])) { + $blocks[$delta] = $facets[$delta] + array('cache' => BLOCK_CACHE_PER_PAGE); + } + } + return $blocks; + + case 'view': + if (apachesolr_has_searched()) { + // Get the query and response. Without these no blocks make sense. + $response = apachesolr_static_response_cache(); + if (empty($response)) { + return; + } + $query = apachesolr_current_query(); + + $facets = apachesolr_get_enabled_facets('api_solr'); + if (empty($facets[$delta])) { + return; + } + + // Get information needed by the taxonomy blocks about limits. + $initial_limits = variable_get('apachesolr_facet_query_initial_limits', array()); + $limit_default = variable_get('apachesolr_facet_query_initial_limit_default', 10); + + $titles = array( + 'ss_api_object_type' => t('Filter by object type'), + 'ss_api_branch_name' => t('Filter by branch name'), + 'ss_api_file_name' => t('Filter by file name'), + ); + $formatters = array( + 'ss_api_object_type' => 'api_solr_format_object_type', + 'ss_api_branch_name' => 'api_solr_format_branch_name', + ); + return apachesolr_facet_block($response, $query, 'api_solr', $delta, $delta, $titles[$delta], isset($formatters[$delta]) ? $formatters[$delta] : FALSE); + } + break; + + case 'configure': + return apachesolr_facetcount_form('api_solr', $delta); + break; + + case 'save': + apachesolr_facetcount_save($edit); + break; + } +} + +/** + * Format an object type based on the internal object type. + */ +function api_solr_format_object_type($object_type) { + $map = array( + 'function' => t('Function'), + 'file' => t('File'), + 'constant' => t('Constant'), + 'group' => t('Group'), + 'global' => t('Global variable'), + ); + return isset($map[$object_type]) ? $map[$object_type] : $object_type; +} + +/** + * Format an branch name based on the internal branch code. + */ +function api_solr_format_branch_name($branch_name) { + $branches = api_get_branches(); + return isset($branches[$branch_name]) ? $branches[$branch_name]->title : $branch_name; +} + + +/** + * Implementation of hook_form_FORM_ID_alter(). + */ +function api_solr_form_apachesolr_search_settings_form_alter(&$form) { + // Display the object_name field boost options. + $form['apachesolr_search_query_fields']['ss_api_object_name']['#access'] = TRUE; +} diff --git parser.inc parser.inc index 2e14261..f83bf88 100644 --- parser.inc +++ parser.inc @@ -480,6 +480,9 @@ function api_save_documentation($docblocks, $branch_name = NULL, $file_name = NU } } + // Allow other modules to act on saving the documentation blocks. + module_invoke_all('api_save_documentation', $docblocks, $branch_name, $file_name); + api_schedule_shutdown(); } @@ -864,7 +867,12 @@ function api_update_branch($branch) { db_query("DELETE FROM {api_file} WHERE did = %d", $doc->did); db_query("DELETE FROM {api_function} WHERE did = %d", $doc->did); db_query("DELETE FROM {api_reference_storage} WHERE from_did = %d OR to_did = %d", $doc->did, $doc->did); + + // Delete the associated node. + node_delete($doc->did); } + + // Schedule a rebuild of needed datastructures. api_schedule_shutdown(); } }