callback_node_access.inc 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. <?php
  2. /**
  3. * @file
  4. * Contains the SearchApiAlterNodeAccess class.
  5. */
  6. /**
  7. * Adds node access information to node indexes.
  8. */
  9. class SearchApiAlterNodeAccess extends SearchApiAbstractAlterCallback {
  10. /**
  11. * Check whether this data-alter callback is applicable for a certain index.
  12. *
  13. * Returns TRUE only for indexes on nodes.
  14. *
  15. * @param SearchApiIndex $index
  16. * The index to check for.
  17. *
  18. * @return boolean
  19. * TRUE if the callback can run on the given index; FALSE otherwise.
  20. */
  21. public function supportsIndex(SearchApiIndex $index) {
  22. // Currently only node access is supported.
  23. return $index->item_type === 'node';
  24. }
  25. /**
  26. * Declare the properties that are (or can be) added to items with this callback.
  27. *
  28. * Adds the "search_api_access_node" property.
  29. *
  30. * @see hook_entity_property_info()
  31. *
  32. * @return array
  33. * Information about all additional properties, as specified by
  34. * hook_entity_property_info() (only the inner "properties" array).
  35. */
  36. public function propertyInfo() {
  37. return array(
  38. 'search_api_access_node' => array(
  39. 'label' => t('Node access information'),
  40. 'description' => t('Data needed to apply node access.'),
  41. 'type' => 'list<token>',
  42. ),
  43. );
  44. }
  45. /**
  46. * Alter items before indexing.
  47. *
  48. * Items which are removed from the array won't be indexed, but will be marked
  49. * as clean for future indexing. This could for instance be used to implement
  50. * some sort of access filter for security purposes (e.g., don't index
  51. * unpublished nodes or comments).
  52. *
  53. * @param array $items
  54. * An array of items to be altered, keyed by item IDs.
  55. */
  56. public function alterItems(array &$items) {
  57. static $account;
  58. if (!isset($account)) {
  59. // Load the anonymous user.
  60. $account = drupal_anonymous_user();
  61. }
  62. foreach ($items as $nid => &$item) {
  63. // Check whether all users have access to the node.
  64. if (!node_access('view', $item, $account)) {
  65. // Get node access grants.
  66. $result = db_query('SELECT * FROM {node_access} WHERE (nid = 0 OR nid = :nid) AND grant_view = 1', array(':nid' => $item->nid));
  67. // Store all grants together with it's realms in the item.
  68. foreach ($result as $grant) {
  69. if (!isset($items[$nid]->search_api_access_node)) {
  70. $items[$nid]->search_api_access_node = array();
  71. }
  72. $items[$nid]->search_api_access_node[] = "node_access_$grant->realm:$grant->gid";
  73. }
  74. }
  75. else {
  76. // Add the generic view grant if we are not using node access or the
  77. // node is viewable by anonymous users.
  78. $items[$nid]->search_api_access_node = array('node_access__all');
  79. }
  80. }
  81. }
  82. /**
  83. * Submit callback for the configuration form.
  84. *
  85. * If the data alteration is being enabled, set "Published" and "Author" to
  86. * "indexed", because both are needed for the node access filter.
  87. */
  88. public function configurationFormSubmit(array $form, array &$values, array &$form_state) {
  89. $old_status = !empty($form_state['index']->options['data_alter_callbacks']['search_api_alter_node_access']['status']);
  90. $new_status = !empty($form_state['values']['callbacks']['search_api_alter_node_access']['status']);
  91. if (!$old_status && $new_status) {
  92. $form_state['index']->options['fields']['status']['type'] = 'boolean';
  93. $form_state['index']->options['fields']['author']['type'] = 'integer';
  94. $form_state['index']->options['fields']['author']['entity_type'] = 'user';
  95. }
  96. return parent::configurationFormSubmit($form, $values, $form_state);
  97. }
  98. }