service.inc 12 KB

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