service.inc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. <?php
  2. /**
  3. * Interface defining the methods search services have to implement.
  4. *
  5. * Before a service object is used, the corresponding server's data will be read
  6. * from the database (see SearchApiAbstractService for a list of fields).
  7. */
  8. interface SearchApiServiceInterface {
  9. /**
  10. * Constructor for a service class, setting the server configuration used with
  11. * this service.
  12. *
  13. * @param SearchApiServer $server
  14. * The server object for this service.
  15. */
  16. public function __construct(SearchApiServer $server);
  17. /**
  18. * Form callback. Might be called on an uninitialized object - in this case,
  19. * the form is for configuring a newly created server.
  20. *
  21. * @return array
  22. * A form array for setting service-specific options.
  23. */
  24. public function configurationForm(array $form, array &$form_state);
  25. /**
  26. * Validation callback for the form returned by configurationForm().
  27. *
  28. * $form_state['server'] will contain the server that is created or edited.
  29. * Use form_error() to flag errors on form elements.
  30. *
  31. * @param array $form
  32. * The form returned by configurationForm().
  33. * @param array $values
  34. * The part of the $form_state['values'] array corresponding to this form.
  35. * @param array $form_state
  36. * The complete form state.
  37. */
  38. public function configurationFormValidate(array $form, array &$values, array &$form_state);
  39. /**
  40. * Submit callback for the form returned by configurationForm().
  41. *
  42. * This method should set the options of this service' server according to
  43. * $values.
  44. *
  45. * @param array $form
  46. * The form returned by configurationForm().
  47. * @param array $values
  48. * The part of the $form_state['values'] array corresponding to this form.
  49. * @param array $form_state
  50. * The complete form state.
  51. */
  52. public function configurationFormSubmit(array $form, array &$values, array &$form_state);
  53. /**
  54. * Determines whether this service class implementation supports a given
  55. * feature. Features are optional extensions to Search API functionality and
  56. * usually defined and used by third-party modules.
  57. *
  58. * There are currently three features defined directly in the Search API
  59. * project:
  60. * - "search_api_facets", by the search_api_facetapi module.
  61. * - "search_api_facets_operator_or", also by the search_api_facetapi module.
  62. * - "search_api_mlt", by the search_api_views module.
  63. * Other contrib modules might define additional features. These should always
  64. * be properly documented in the module by which they are defined.
  65. *
  66. * @param string $feature
  67. * The name of the optional feature.
  68. *
  69. * @return boolean
  70. * TRUE if this service knows and supports the specified feature. FALSE
  71. * otherwise.
  72. */
  73. public function supportsFeature($feature);
  74. /**
  75. * View this server's settings. Output can be HTML or a render array, a <dl>
  76. * listing all relevant settings is preferred.
  77. */
  78. public function viewSettings();
  79. /**
  80. * Called once, when the server is first created. Allows it to set up its
  81. * necessary infrastructure.
  82. */
  83. public function postCreate();
  84. /**
  85. * Notifies this server that its fields are about to be updated. The server's
  86. * $original property can be used to inspect the old property values.
  87. *
  88. * @return
  89. * TRUE, if the update requires reindexing of all content on the server.
  90. */
  91. public function postUpdate();
  92. /**
  93. * Notifies this server that it is about to be deleted from the database and
  94. * should therefore clean up, if appropriate.
  95. *
  96. * Note that you shouldn't call the server's save() method, or any
  97. * methods that might do that, from inside of this method as the server isn't
  98. * present in the database anymore at this point.
  99. */
  100. public function preDelete();
  101. /**
  102. * Add a new index to this server.
  103. *
  104. * If the index was already added to the server, the object should treat this
  105. * as if removeIndex() and then addIndex() were called.
  106. *
  107. * @param SearchApiIndex $index
  108. * The index to add.
  109. */
  110. public function addIndex(SearchApiIndex $index);
  111. /**
  112. * Notify the server that the indexed field settings for the index have
  113. * changed.
  114. * If any user action is necessary as a result of this, the method should
  115. * use drupal_set_message() to notify the user.
  116. *
  117. * @param SearchApiIndex $index
  118. * The updated index.
  119. *
  120. * @return
  121. * TRUE, if this change affected the server in any way that forces it to
  122. * re-index the content. FALSE otherwise.
  123. */
  124. public function fieldsUpdated(SearchApiIndex $index);
  125. /**
  126. * Remove an index from this server.
  127. *
  128. * This might mean that the index has been deleted, or reassigned to a
  129. * different server. If you need to distinguish between these cases, inspect
  130. * $index->server.
  131. *
  132. * If the index wasn't added to the server, the method call should be ignored.
  133. *
  134. * @param $index
  135. * Either an object representing the index to remove, or its machine name
  136. * (if the index was completely deleted).
  137. */
  138. public function removeIndex($index);
  139. /**
  140. * Index the specified items.
  141. *
  142. * @param SearchApiIndex $index
  143. * The search index for which items should be indexed.
  144. * @param array $items
  145. * An array of items to be indexed, keyed by their id. The values are
  146. * associative arrays of the fields to be stored, where each field is an
  147. * array with the following keys:
  148. * - type: One of the data types recognized by the Search API, or the
  149. * special type "tokens" for fulltext fields.
  150. * - original_type: The original type of the property, as defined by the
  151. * datasource controller for the index's item type.
  152. * - value: The value to index.
  153. *
  154. * The special field "search_api_language" contains the item's language and
  155. * should always be indexed.
  156. *
  157. * The value of fields with the "tokens" type is an array of tokens. Each
  158. * token is an array containing the following keys:
  159. * - value: The word that the token represents.
  160. * - score: A score for the importance of that word.
  161. *
  162. * @return array
  163. * An array of the ids of all items that were successfully indexed.
  164. *
  165. * @throws SearchApiException
  166. * If indexing was prevented by a fundamental configuration error.
  167. */
  168. public function indexItems(SearchApiIndex $index, array $items);
  169. /**
  170. * Delete items from an index on this server.
  171. *
  172. * Might be either used to delete some items (given by their ids) from a
  173. * specified index, or all items from that index, or all items from all
  174. * indexes on this server.
  175. *
  176. * @param $ids
  177. * Either an array containing the ids of the items that should be deleted,
  178. * or 'all' if all items should be deleted. Other formats might be
  179. * recognized by implementing classes, but these are not standardized.
  180. * @param SearchApiIndex $index
  181. * The index from which items should be deleted, or NULL if all indexes on
  182. * this server should be cleared (then, $ids has to be 'all').
  183. */
  184. public function deleteItems($ids = 'all', SearchApiIndex $index = NULL);
  185. /**
  186. * Create a query object for searching on an index lying on this server.
  187. *
  188. * @param SearchApiIndex $index
  189. * The index to search on.
  190. * @param $options
  191. * Associative array of options configuring this query. See
  192. * SearchApiQueryInterface::__construct().
  193. *
  194. * @return SearchApiQueryInterface
  195. * An object for searching the given index.
  196. *
  197. * @throws SearchApiException
  198. * If the server is currently disabled.
  199. */
  200. public function query(SearchApiIndex $index, $options = array());
  201. /**
  202. * Executes a search on the server represented by this object.
  203. *
  204. * @param $query
  205. * The SearchApiQueryInterface object to execute.
  206. *
  207. * @return array
  208. * An associative array containing the search results, as required by
  209. * SearchApiQueryInterface::execute().
  210. *
  211. * @throws SearchApiException
  212. * If an error prevented the search from completing.
  213. */
  214. public function search(SearchApiQueryInterface $query);
  215. }
  216. /**
  217. * Abstract class with generic implementation of most service methods.
  218. */
  219. abstract class SearchApiAbstractService implements SearchApiServiceInterface {
  220. /**
  221. * @var SearchApiServer
  222. */
  223. protected $server;
  224. /**
  225. * Direct reference to the server's $options property.
  226. *
  227. * @var array
  228. */
  229. protected $options = array();
  230. /**
  231. * Constructor for a service class, setting the server configuration used with
  232. * this service.
  233. *
  234. * The default implementation sets $this->server and $this->options.
  235. *
  236. * @param SearchApiServer $server
  237. * The server object for this service.
  238. */
  239. public function __construct(SearchApiServer $server) {
  240. $this->server = $server;
  241. $this->options = &$server->options;
  242. }
  243. /**
  244. * Form callback. Might be called on an uninitialized object - in this case,
  245. * the form is for configuring a newly created server.
  246. *
  247. * Returns an empty form by default.
  248. *
  249. * @return array
  250. * A form array for setting service-specific options.
  251. */
  252. public function configurationForm(array $form, array &$form_state) {
  253. return array();
  254. }
  255. /**
  256. * Validation callback for the form returned by configurationForm().
  257. *
  258. * Does nothing by default.
  259. *
  260. * @param array $form
  261. * The form returned by configurationForm().
  262. * @param array $values
  263. * The part of the $form_state['values'] array corresponding to this form.
  264. * @param array $form_state
  265. * The complete form state.
  266. */
  267. public function configurationFormValidate(array $form, array &$values, array &$form_state) {
  268. return;
  269. }
  270. /**
  271. * Submit callback for the form returned by configurationForm().
  272. *
  273. * The default implementation just ensures that additional elements in
  274. * $options, not present in the form, don't get lost at the update.
  275. *
  276. * @param array $form
  277. * The form returned by configurationForm().
  278. * @param array $values
  279. * The part of the $form_state['values'] array corresponding to this form.
  280. * @param array $form_state
  281. * The complete form state.
  282. */
  283. public function configurationFormSubmit(array $form, array &$values, array &$form_state) {
  284. if (!empty($this->options)) {
  285. $values += $this->options;
  286. }
  287. $this->options = $values;
  288. }
  289. /**
  290. * Determines whether this service class implementation supports a given
  291. * feature. Features are optional extensions to Search API functionality and
  292. * usually defined and used by third-party modules.
  293. *
  294. * There are currently three features defined directly in the Search API
  295. * project:
  296. * - "search_api_facets", by the search_api_facetapi module.
  297. * - "search_api_facets_operator_or", also by the search_api_facetapi module.
  298. * - "search_api_mlt", by the search_api_views module.
  299. * Other contrib modules might define additional features. These should always
  300. * be properly documented in the module by which they are defined.
  301. *
  302. * @param string $feature
  303. * The name of the optional feature.
  304. *
  305. * @return boolean
  306. * TRUE if this service knows and supports the specified feature. FALSE
  307. * otherwise.
  308. */
  309. public function supportsFeature($feature) {
  310. return FALSE;
  311. }
  312. /**
  313. * View this server's settings. Output can be HTML or a render array, a <dl>
  314. * listing all relevant settings is preferred.
  315. *
  316. * The default implementation does a crude output as a definition list, with
  317. * option names taken from the configuration form.
  318. */
  319. public function viewSettings() {
  320. $output = '';
  321. $form = $form_state = array();
  322. $option_form = $this->configurationForm($form, $form_state);
  323. $option_names = array();
  324. foreach ($option_form as $key => $element) {
  325. if (isset($element['#title']) && isset($this->options[$key])) {
  326. $option_names[$key] = $element['#title'];
  327. }
  328. }
  329. foreach ($option_names as $key => $name) {
  330. $value = $this->options[$key];
  331. $output .= '<dt>' . check_plain($name) . '</dt>' . "\n";
  332. $output .= '<dd>' . nl2br(check_plain(print_r($value, TRUE))) . '</dd>' . "\n";
  333. }
  334. return $output ? "<dl>\n$output</dl>" : '';
  335. }
  336. /**
  337. * Called once, when the server is first created. Allows it to set up its
  338. * necessary infrastructure.
  339. *
  340. * Does nothing, by default.
  341. */
  342. public function postCreate() {
  343. return;
  344. }
  345. /**
  346. * Notifies this server that its fields are about to be updated. The server's
  347. * $original property can be used to inspect the old property values.
  348. *
  349. * @return
  350. * TRUE, if the update requires reindexing of all content on the server.
  351. */
  352. public function postUpdate() {
  353. return FALSE;
  354. }
  355. /**
  356. * Notifies this server that it is about to be deleted from the database and
  357. * should therefore clean up, if appropriate.
  358. *
  359. * Note that you shouldn't call the server's save() method, or any
  360. * methods that might do that, from inside of this method as the server isn't
  361. * present in the database anymore at this point.
  362. *
  363. * By default, deletes all indexes from this server.
  364. */
  365. public function preDelete() {
  366. $indexes = search_api_index_load_multiple(FALSE, array('server' => $this->server->machine_name));
  367. foreach ($indexes as $index) {
  368. $this->removeIndex($index);
  369. }
  370. }
  371. /**
  372. * Add a new index to this server.
  373. *
  374. * Does nothing, by default.
  375. *
  376. * @param SearchApiIndex $index
  377. * The index to add.
  378. */
  379. public function addIndex(SearchApiIndex $index) {
  380. return;
  381. }
  382. /**
  383. * Notify the server that the indexed field settings for the index have
  384. * changed.
  385. * If any user action is necessary as a result of this, the method should
  386. * use drupal_set_message() to notify the user.
  387. *
  388. * @param SearchApiIndex $index
  389. * The updated index.
  390. *
  391. * @return
  392. * TRUE, if this change affected the server in any way that forces it to
  393. * re-index the content. FALSE otherwise.
  394. */
  395. public function fieldsUpdated(SearchApiIndex $index) {
  396. return FALSE;
  397. }
  398. /**
  399. * Remove an index from this server.
  400. *
  401. * This might mean that the index has been deleted, or reassigned to a
  402. * different server. If you need to distinguish between these cases, inspect
  403. * $index->server.
  404. *
  405. * By default, removes all items from that index.
  406. *
  407. * @param $index
  408. * Either an object representing the index to remove, or its machine name
  409. * (if the index was completely deleted).
  410. */
  411. public function removeIndex($index) {
  412. $this->deleteItems('all', $index);
  413. }
  414. /**
  415. * Create a query object for searching on an index lying on this server.
  416. *
  417. * @param SearchApiIndex $index
  418. * The index to search on.
  419. * @param $options
  420. * Associative array of options configuring this query. See
  421. * SearchApiQueryInterface::__construct().
  422. *
  423. * @return SearchApiQueryInterface
  424. * An object for searching the given index.
  425. *
  426. * @throws SearchApiException
  427. * If the server is currently disabled.
  428. */
  429. public function query(SearchApiIndex $index, $options = array()) {
  430. return new SearchApiQuery($index, $options);
  431. }
  432. }