apachesolr.api.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. <?php
  2. /**
  3. * @file
  4. * Exposed Hooks in 7.x:
  5. */
  6. /**
  7. * Lets modules know when the default environment is changed.
  8. *
  9. * @param string $env_id
  10. * The machine name of the environment.
  11. * @param string $old_env_id
  12. * The old machine name of the environment.
  13. */
  14. function hook_apachesolr_default_environment($env_id, $old_env_id) {
  15. $page = apachesolr_search_page_load('core_search');
  16. if ($page && $page['env_id'] != $env_id) {
  17. $page['env_id'] = $env_id;
  18. apachesolr_search_page_save($page);
  19. }
  20. }
  21. /**
  22. * Add index mappings for Field API types. The default mappings array
  23. * handles just list fields and taxonomy term reference fields, such as:
  24. *
  25. * $mappings['list_text'] = array(
  26. * 'indexing_callback' => array('apachesolr_fields_list_indexing_callback'),
  27. * 'index_type' => 'string',
  28. * 'map callback' => 'apachesolr_fields_list_display_callback',
  29. * 'facets' => TRUE,
  30. * ),
  31. *
  32. * In your implementation you can add additional field types such as:
  33. * $mappings['number_integer']['number'] = array(...);
  34. *
  35. * You can also add mapping for a specific field. This will take precedence
  36. * over any mapping for a general field type. A field-specific mapping would
  37. * looks like:
  38. * $mappings['per-field']['field_model_name'] = array(...);
  39. *
  40. * Much more information can be found below in the example implementation or in
  41. * facetapi.api.php. If you feel restricted with the options as set below
  42. * there is nothing that stops you from implementing facetapi directly. However
  43. * it is recommended to not directly talk to solr fields since this could break
  44. * in the future.
  45. *
  46. * @return array $mappings
  47. * An associative array of mappings as defined by modules that implement
  48. * hook_apachesolr_field_mappings().
  49. */
  50. function hook_apachesolr_field_mappings() {
  51. $mappings = array(
  52. // Example for a field API type. See extensive documentation below
  53. 'number_float' => array(
  54. 'indexing_callback' => array('apachesolr_fields_default_indexing_callback'),
  55. 'index_type' => 'tfloat',
  56. 'facets' => TRUE,
  57. 'query types' => array('term', 'numeric_range'),
  58. 'query type' => 'term',
  59. 'facet mincount allowed' => TRUE,
  60. ),
  61. // Example for a field API field
  62. 'per-field' => array(
  63. // machine name of the field in Field API
  64. 'field_price' => array(
  65. // REQUIRED FIELDS //
  66. // Function callback to return the value that will be put in to
  67. // the solr index
  68. 'indexing_callback' => array('apachesolr_fields_default_indexing_callback'),
  69. // NON REQUIRED FIELDS //
  70. // See apachesolr_index_key() for the correct type. Defaults string
  71. 'index_type' => 'string',
  72. // How to display the values when they return as a facet
  73. 'map callback' => 'apachesolr_fields_list_facet_map_callback',
  74. // Does your facet have a dynamic name? Add function call here and will
  75. // have the name of the return value
  76. 'name callback' => FALSE,
  77. // If a custom field needs to be searchable but does not need to be faceted you
  78. // can change the 'facets' parameter to FALSE.
  79. 'facets' => FALSE,
  80. // Do you want to allow items without value
  81. 'facet missing allowed' => FALSE,
  82. // (optional) Whether or not the facet supports the
  83. // "minimum facet count" setting. Defaults to TRUE.
  84. 'facet mincount allowed' => FALSE,
  85. // Field API allows any field to be multi-valued.
  86. // If we set this to false we are able to sort
  87. 'dependency plugins' => array('bundle', 'role'),
  88. // Does your solr index has a hierarchy?
  89. // See facetapi_get_taxonomy_hierarchy for details or
  90. // view the mapping of taxonomy_term_reference
  91. 'hierarchy callback' => FALSE,
  92. // There are different query types to return information from Solr
  93. // term : Regular strings
  94. // date : Everything regarding dates
  95. // numeric_range : Useful when you have widgets that depend
  96. // on statistics coming from Solr
  97. 'query types' => array('term', 'numeric_range'),
  98. // Backwards compatible with previous facetapi versions.
  99. // Pick the main query type
  100. 'query type' => 'term',
  101. // What dependencies do you have (see facetapi)
  102. 'multiple' => TRUE,
  103. ),
  104. ),
  105. );
  106. return $mappings;
  107. }
  108. /**
  109. * Alter hook for apachesolr_field_mappings().
  110. *
  111. * Add or alter index mappings for Field API types. The default mappings array
  112. * handles just list fields and taxonomy term reference fields, in the same way
  113. * as documented in hook_apachesolr_field_mappings.
  114. *
  115. * @param array $mappings
  116. * An associative array of mappings as defined by modules that implement
  117. * hook_apachesolr_field_mappings().
  118. * @param string $entity_type
  119. * The entity type for which you want to alter the field mappings
  120. */
  121. function hook_apachesolr_field_mappings_alter(array &$mappings, $entity_type) {
  122. // Enable indexing for text fields
  123. $mappings['text'] = array(
  124. 'indexing_callback' => array('apachesolr_fields_default_indexing_callback'),
  125. 'map callback' => '',
  126. 'index_type' => 'string',
  127. 'facets' => TRUE,
  128. 'facet missing allowed' => TRUE,
  129. 'dependency plugins' => array('bundle', 'role'),
  130. 'hierarchy callback' => FALSE,
  131. 'name callback' => '',
  132. 'facet mincount allowed' => FALSE,
  133. 'multiple' => FALSE,
  134. );
  135. // Add our per field mapping here so we can sort on the
  136. // price by making it single. Solr cannot sort on multivalued fields
  137. // field_price is our identifier of a custom field, and it was decided to
  138. // index in the same way as a number_float field.
  139. $mappings['per-field']['field_price'] = $mappings['number_float'];
  140. $mappings['per-field']['field_price']['multiple'] = FALSE;
  141. }
  142. /**
  143. * Prepare the query by adding parameters, sorts, etc.
  144. *
  145. * This hook is invoked before the query is cached. The cached query is used
  146. * after the search such as for building facet and sort blocks, so parameters
  147. * added during this hook may be visible to end users.
  148. *
  149. * This is otherwise the same as HOOK_apachesolr_query_alter(), but runs before
  150. * it.
  151. *
  152. * @param DrupalSolrQueryInterface $query
  153. * An object implementing DrupalSolrQueryInterface. No need for &.
  154. */
  155. function hook_apachesolr_query_prepare(DrupalSolrQueryInterface $query) {
  156. // Add a sort on the node ID.
  157. $query->setAvailableSort('entity_id', array(
  158. 'title' => t('Node ID'),
  159. 'default' => 'asc',
  160. ));
  161. }
  162. /**
  163. * Assigns a readable name to your custom solr field
  164. *
  165. * @param array $map
  166. */
  167. function hook_apachesolr_field_name_map_alter(array &$map) {
  168. $map['xs_node'] = t('The full node object');
  169. }
  170. /**
  171. * Alter the query after it's prepared and cached.
  172. *
  173. * Any module performing a search should call
  174. * drupal_alter('apachesolr_query', $query). That function then invokes this
  175. * hook. It allows modules to modify the query object and its parameters.
  176. *
  177. * A module implementing HOOK_apachesolr_query_alter() may set
  178. * $query->abort_search to TRUE to flag the query to be aborted.
  179. *
  180. * @param DrupalSolrQueryInterface $query
  181. * An object implementing DrupalSolrQueryInterface. No need for &.
  182. *
  183. * @see /admin/reports/apachesolr
  184. * - This report displays the active solr index fields and can help you
  185. * create Solr filters based on the data currently in your system
  186. */
  187. function hook_apachesolr_query_alter(DrupalSolrQueryInterface $query) {
  188. // I only want to see articles by the admin.
  189. //
  190. // NOTE: this "is_uid" filter does NOT refer to the English word "is"
  191. // It is a combination of flags representing Integer-Single, which is
  192. // abbreviated with the letters i and s.
  193. //
  194. // @see the <dynamicField> definitions in schema.xml or schema-solr3.xml
  195. $query->addFilter("is_uid", 1);
  196. // Only search titles.
  197. $query->replaceParam('qf', 'label');
  198. // Restrict results to a single content type (use machine name).
  199. $query->addFilter('bundle', 'my_content_type');
  200. // Exclude results by setting the third argument of addFilter to TRUE.
  201. // This filter will return all content types EXCEPT my_content_type nodes.
  202. $query->addFilter('bundle', 'my_content_type', TRUE);
  203. // Restrict results to several content types (use machine names).
  204. // You could also solve this using the SolrFilterSubQuery object and append it
  205. // to the original query.
  206. $content_types = array(
  207. 'content_type_1',
  208. 'content_type_2',
  209. );
  210. $query->addFilter('bundle', '('. implode(' OR ', $content_types) .')');
  211. }
  212. /**
  213. * Allows a module to modify the delete query.
  214. *
  215. * @param string $query
  216. * This is not an instance of DrupalSolrQueryInterface, it is the raw query
  217. * that is being sent to Solr. Defaults to "*:*".
  218. */
  219. function hook_apachesolr_delete_by_query_alter(&$query) {
  220. // Use the site hash so that you only delete this site's content.
  221. if ($query == '*:*') {
  222. $query = 'hash:' . apachesolr_site_hash();
  223. }
  224. else {
  225. $query .= ' AND hash:' . apachesolr_site_hash();
  226. }
  227. }
  228. /**
  229. * This is the place to look for the replacement to hook_apachesolr_node_exclude
  230. * You should define a replacement for the status callback and return
  231. * FALSE for entities which you do not want to appear in the index and TRUE for
  232. * those that you want to include
  233. */
  234. /**
  235. * This is invoked for each entity that is being inspected to be added to the
  236. * index. if any module returns TRUE, the entity is skipped for indexing.
  237. *
  238. * @param string $entity_id
  239. * @param string $entity_type
  240. * @param object $row
  241. * A complete set of data from the indexing table.
  242. * @param string $env_id
  243. * The machine name of the environment.
  244. * @return boolean
  245. */
  246. function hook_apachesolr_exclude($entity_id, $entity_type, $row, $env_id) {
  247. // Never index media entities to core_1
  248. if ($entity_type == 'media' && $env_id == 'core_1') {
  249. return TRUE;
  250. }
  251. return FALSE;
  252. }
  253. /**
  254. * This is invoked for each entity from the type of ENTITY_TYPE that is being
  255. * inspected to be added to the index. if any module returns TRUE, 
  256. * the entity is skipped for indexing.
  257. *
  258. * @param string $entity_id
  259. * @param object $row
  260. * A complete set of data from the indexing table.
  261. * @param string $env_id
  262. * The machine name of the environment.
  263. * @return boolean
  264. */
  265. function hook_apachesolr_ENTITY_TYPE_exclude($entity_id, $row, $env_id) {
  266. // Never index ENTITY_TYPE to core_1
  267. if ($env_id == 'core_1') {
  268. return TRUE;
  269. }
  270. return FALSE;
  271. }
  272. /**
  273. * Add information to index other entities.
  274. * There are some modules in http://drupal.org that can give a good example of
  275. * custom entity indexing such as apachesolr_user, apachesolr_term
  276. *
  277. * @param array $entity_info
  278. */
  279. function hook_apachesolr_entity_info_alter(array &$entity_info) {
  280. // REQUIRED VALUES
  281. // myentity should be replaced with user/node/custom entity
  282. $entity_info['node'] = array();
  283. // Set this entity as indexable
  284. $entity_info['node']['indexable'] = TRUE;
  285. // Validate each entity if it can be indexed or not. Multiple callbacks are
  286. // allowed. If one of them returns false it won't be indexed
  287. $entity_info['node']['status callback'][] = 'apachesolr_index_node_status_callback';
  288. // Build up a custom document.
  289. $entity_info['node']['document callback'][] = 'apachesolr_index_node_solr_document';
  290. // What to do when a reindex is issued. Most probably this will reset all the
  291. // items in the index_table
  292. $entity_info['node']['reindex callback'] = 'apachesolr_index_node_solr_reindex';
  293. // OPTIONAL VALUES
  294. // Index in a separate table? Useful for huge datasets.
  295. $entity_info['node']['index_table'] = 'apachesolr_index_entities_node';
  296. // Execute custom callback on each cron run.
  297. // See apachesolr_index_node_check_table
  298. $entity_info['node']['cron_check'] = 'apachesolr_index_node_check_table';
  299. // Specific output processing for the results
  300. $entity_info['node']['result callback'] = 'apachesolr_search_node_result';
  301. // BUNDLE SPECIFIC OVERRIDES
  302. // The following can be overridden on a per-bundle basis.
  303. // The bundle-specific settings will take precedence over the entity settings.
  304. $entity_info['node']['bundles']['page']['apachesolr']['result callback'] = 'apachesolr_search_node_result';
  305. $entity_info['node']['bundles']['page']['apachesolr']['status callback'][] = 'apachesolr_index_node_status_callback';
  306. $entity_info['node']['bundles']['page']['apachesolr']['document callback'][] = 'apachesolr_index_node_solr_document';
  307. }
  308. /**
  309. * This is invoked by apachesolr_search.module for each document returned in a
  310. * search. This has been introduced in 6.x-beta7 as a replacement for the call
  311. * to HOOK_nodeapi().
  312. *
  313. * @param ApacheSolrDocument $document
  314. * The ApacheSolrDocument instance.
  315. * @param array $extra
  316. * @param DrupalSolrQueryInterface $query
  317. */
  318. function hook_apachesolr_search_result_alter(ApacheSolrDocument $document, array &$extra, DrupalSolrQueryInterface $query) {
  319. }
  320. /**
  321. * This is invoked by apachesolr_search.module for the whole resultset returned
  322. * in a search.
  323. *
  324. * @param array $results
  325. * The returned search results.
  326. * @param DrupalSolrQueryInterface $query
  327. * The query for which we want to process the results from
  328. */
  329. function hook_apachesolr_process_results(array &$results, DrupalSolrQueryInterface $query) {
  330. foreach ($results as $id => $result) {
  331. $results[$id]['title'] = t('[Result] !title', array('!title' => $result['title']));
  332. }
  333. }
  334. /**
  335. * Respond to search environment deletion.
  336. *
  337. * This hook is invoked from apachesolr_environment_delete() after the
  338. * environment is removed from the database.
  339. *
  340. * @param array $environment
  341. * The environment object that is being deleted.
  342. */
  343. function hook_apachesolr_environment_delete(array $environment) {
  344. }
  345. /**
  346. *
  347. * Modify the build array for any search output build by Apache Solr
  348. * This includes core and custom pages and makes it very easy to modify both
  349. * of them at once
  350. *
  351. * @param array $build
  352. * @param array $search_page
  353. */
  354. function hook_apachesolr_search_page_alter(array &$build, array $search_page) {
  355. // Adds a text to the top of the page
  356. $info = array('#markup' => t('Add information to every search page'));
  357. array_unshift($build, $info);
  358. }
  359. /**
  360. * Modify the search types as found in the search pages administration
  361. *
  362. * @param array $search_types
  363. */
  364. function hook_apachesolr_search_types_alter(&$search_types) {
  365. $search_types['ss_language'] = array(
  366. 'name' => apachesolr_field_name_map('ss_language'),
  367. 'default menu' => 'search/language/%',
  368. 'title callback' => 'custom_title_callback',
  369. );
  370. }
  371. /**
  372. * Build the documents before sending them to Solr.
  373. * The function is the follow-up for apachesolr_update_index
  374. *
  375. * @param ApacheSolrDocument $document
  376. * @param object $entity
  377. * @param string $entity_type
  378. * @param string $env_id
  379. * The machine name of the environment.
  380. */
  381. function hook_apachesolr_index_document_build(ApacheSolrDocument $document, $entity, $entity_type, $env_id) {
  382. }
  383. /**
  384. * Build the documents before sending them to Solr.
  385. *
  386. * Supports all types of
  387. * hook_apachesolr_index_document_build_' . $entity_type($documents[$id], $entity, $env_id);
  388. *
  389. * The function is the follow-up for apachesolr_update_index but then for
  390. * specific entity types
  391. *
  392. * @param ApacheSolrDocument $document
  393. * @param object $entity
  394. * @param string $env_id
  395. * The machine name of the environment.
  396. */
  397. function hook_apachesolr_index_document_build_ENTITY_TYPE(ApacheSolrDocument $document, $entity, $env_id) {
  398. // Index field_main_image as a separate field
  399. if ($entity->type == 'profile') {
  400. $user = user_load(array('uid' => $entity->uid));
  401. // Hard coded field, not recommended for inexperienced users.
  402. $document->setMultiValue('sm_field_main_image', $user->picture);
  403. }
  404. }
  405. /**
  406. * Alter the prepared documents from one entity before sending them to Solr.
  407. *
  408. * @param $documents
  409. * Array of ApacheSolrDocument objects.
  410. * @param object $entity
  411. * @param string $entity_type
  412. * @param string $env_id
  413. * The machine name of the environment.
  414. */
  415. function hook_apachesolr_index_documents_alter(array &$documents, $entity, $entity_type, $env_id) {
  416. // Do whatever altering you need here
  417. }
  418. /**
  419. * Modify the returned spellings suggestions. The environment is available
  420. * as an argument so the search query can be retrieved if necessary
  421. *
  422. * @param array $suggestions
  423. * @param string $env_id
  424. */
  425. function hook_apachesolr_suggestions_alter(&$suggestions, $env_id) {
  426. // Modify the suggestions here
  427. }