diff --git a/includes/callback_comment_access.inc b/includes/callback_comment_access.inc index e6273530..6fbe8323 100644 --- a/includes/callback_comment_access.inc +++ b/includes/callback_comment_access.inc @@ -12,10 +12,16 @@ class SearchApiAlterCommentAccess extends SearchApiAlterNodeAccess { /** * Overrides SearchApiAlterNodeAccess::supportsIndex(). * - * Returns TRUE only for indexes on comments. + * Returns TRUE only for indexes on comments or multi-entity indexes that + * include comments. */ public function supportsIndex(SearchApiIndex $index) { - return $index->getEntityType() === 'comment'; + if ($this->isMultiEntityIndex($index)) { + return in_array('comment', $index->options['datasource']['types']); + } + else { + return $index->getEntityType() == 'comment'; + } } /** @@ -24,7 +30,16 @@ public function supportsIndex(SearchApiIndex $index) { * Returns the comment's node, instead of the item (i.e., the comment) itself. */ protected function getNode($item) { - return node_load($item->nid); + if ($this->isMultiEntityIndex()) { + if ($item->item_type !== 'comment') { + return NULL; + } + $nid = $item->comment->nid; + } + else { + $nid = $item->nid; + } + return node_load($nid); } /** diff --git a/includes/callback_node_access.inc b/includes/callback_node_access.inc index 27828c9c..93775664 100644 --- a/includes/callback_node_access.inc +++ b/includes/callback_node_access.inc @@ -92,20 +92,11 @@ public function alterItems(array &$items) { */ protected function getNode($item) { if ($this->isMultiEntityIndex()) { - // For multi-entity indexes, check the item is a node. - if ($item->item_type == 'node') { - // The node is stored on a property of the item. - return $item->node; - } - else { - // Not a node. - return NULL; - } - } - else { - // Normal node index: the whole item is the node. - return $item; + // For multi-entity indexes, check whether the item is a node. + return $item->item_type == 'node' ? $item->node : NULL; } + // Normal node index: the whole item is the node. + return $item; } /** diff --git a/includes/callback_node_status.inc b/includes/callback_node_status.inc index 41d463ee..278ad1b3 100644 --- a/includes/callback_node_status.inc +++ b/includes/callback_node_status.inc @@ -40,16 +40,12 @@ public function supportsIndex(SearchApiIndex $index) { * An array of items to be altered, keyed by item IDs. */ public function alterItems(array &$items) { - foreach ($items as $id => &$item) { + foreach ($items as $id => $item) { $node = $this->getNode($item); // Skip non-node items. - if (empty($node)) { - continue; - } - - if (empty($node->status)) { - $this->removeItem($items, $item); + if (!empty($node) && empty($node->status)) { + unset($items[$id]); } } } @@ -57,14 +53,10 @@ public function alterItems(array &$items) { /** * Retrieves the node related to a search item. * - * In the default implementation for nodes, the item is already the node. - * Subclasses may override this to easily provide node access checks for - * items related to nodes. - * - * @param $item + * @param object $item * The item which is being indexed. * - * @return + * @return object|null * Either the node object, or NULL if the current item is not a node. */ protected function getNode($item) { @@ -85,21 +77,4 @@ protected function getNode($item) { } } - /** - * Remove an item from the array of items to index. - * - * @param array $items - * An array of items being altered, keyed by item IDs. - * @param $item_to_remove - * The item that is to be removed from the $items array. - */ - protected function removeItem(array &$items, $item_to_remove) { - if ($this->isMultiEntityIndex()) { - unset($items[$item_to_remove->item_id]); - } - else { - unset($items[$item_to_remove->nid]); - } - } - } diff --git a/search_api.module b/search_api.module index 54541580..82eb5852 100644 --- a/search_api.module +++ b/search_api.module @@ -2109,7 +2109,7 @@ function search_api_search_api_query_alter(SearchApiQueryInterface $query) { * @throws SearchApiException * If not all necessary fields are indexed on the index. */ -function _search_api_query_add_node_access(SearchApiIndex $index, $account, SearchApiQueryInterface $query) { +function _search_api_query_add_node_access($account, SearchApiQueryInterface $query) { // Don't do anything if the user can access all content. if (user_access('bypass node access', $account)) { return; @@ -2117,7 +2117,9 @@ function _search_api_query_add_node_access(SearchApiIndex $index, $account, Sear $affected_types = array(); $unaffected_types = array(); + $status_field = NULL; + $index = $query->getIndex(); // Gather the affected and unaffected entity types. if ($index->item_type === 'multiple') { $all_types = array(); @@ -2125,8 +2127,9 @@ function _search_api_query_add_node_access(SearchApiIndex $index, $account, Sear $all_types = drupal_map_assoc($index->options['datasource']['types']); } foreach ($all_types as $type) { - if (in_array($type, ['node', 'comment'])) { + if (in_array($type, array('node', 'comment'))) { $affected_types[$type] = $type; + $status_field = "$type:status"; } else { $unaffected_types[$type] = $type; @@ -2155,7 +2158,7 @@ function _search_api_query_add_node_access(SearchApiIndex $index, $account, Sear // If there are no "other" datasources, we don't need the nested OR, // however, and can add the inner conditions directly to the query. if ($unaffected_types) { - $outer_conditions = $query->createFilter('OR', ['content_access']); + $outer_conditions = $query->createFilter('OR', array('content_access')); $query->filter($outer_conditions); foreach ($unaffected_types as $type) { $outer_conditions->condition('item_type', $type); @@ -2181,8 +2184,11 @@ function _search_api_query_add_node_access(SearchApiIndex $index, $account, Sear // remove all results of node or comment datasources. Otherwise, we should // not return any results at all. if (!$unaffected_types) { - // TODO: Not sure what (if anything) we actually need to do here? - // $query->abort($this->t('You have no access to any results in this search.')); + // Simple hack for returning no results. + $query->condition($status_field, 0); + $query->condition($status_field, 1); + watchdog('search_api', 'User @name tried to execute a search, but cannot access content.', array('@name' => theme('username', array('account' => $account))), WATCHDOG_NOTICE); + } return; } @@ -2190,7 +2196,7 @@ function _search_api_query_add_node_access(SearchApiIndex $index, $account, Sear // Collect all the required fields that need to be part of the index. $unpublished_own = user_access('view own unpublished content', $account); - $enabled_conditions = $query->createFilter('OR', ['content_access_enabled']); + $enabled_conditions = $query->createFilter('OR', array('content_access_enabled')); foreach ($affected_types as $entity_type) { // If this is a comment datasource, or users cannot view their own // unpublished nodes, a simple filter on "status" is enough. Otherwise, @@ -2210,7 +2216,7 @@ function _search_api_query_add_node_access(SearchApiIndex $index, $account, Sear $access_conditions->filter($enabled_conditions); // Filter by the user's node access grants. - $grants_conditions = $query->createFilter('OR', ['content_access_grants']); + $grants_conditions = $query->createFilter('OR', array('content_access_grants')); $grants = node_access_grants('view', $account); foreach ($grants as $realm => $gids) { foreach ($gids as $gid) {