$node->nid)); foreach($result as $grant){ $key = 'nodeaccess_' . apachesolr_site_hash() . '_' . $grant->realm; $document->setMultiValue($key, $grant->gid); } } else { // Add the generic view grant if we are not using // node access or the node is viewable by anonymous users. $document->setMultiValue('nodeaccess_all', 0); } } /** * Creates a Solr query for a given user * * @param $account an account to get grants for and build a solr query * * @throws Exception */ function apachesolr_nodeaccess_build_subquery($account) { if (!user_access('access content', $account)) { throw new Exception('No access'); } $node_access_query = apachesolr_drupal_query(); if (user_access('bypass node access', $account)) { // Access all content from the current site, or public content. $node_access_query->add_filter('nodeaccess_all', 0); $node_access_query->add_filter('hash', apachesolr_site_hash()); } else { // Get node access grants. $grants = node_access_grants('view', $account); foreach ($grants as $realm => $gids) { foreach ($gids as $gid) { $node_access_query->add_filter('nodeaccess_' . apachesolr_site_hash() . '_' . $realm, $gid); } } $node_access_query->add_filter('nodeaccess_all', 0); } return $node_access_query; } /** * Implements hook_apachesolr_modify_query(). */ function apachesolr_nodeaccess_apachesolr_modify_query(DrupalSolrQueryInterface $query, $caller = 'apachesolr_search') { global $user; try { $subquery = apachesolr_nodeaccess_build_subquery($user); $query->add_subquery($subquery, 'OR'); } catch (Exception $e) { watchdog("apachesolr_nodeaccess", 'User %name (UID:!uid) cannot search: @message', array('%name' => $user->name, '!uid' => $user->uid, '@message' => $e->getMessage())); // Returning TRUE aborts the search. return TRUE; } } /** * Implements hook_node_insert(). * hook_node*() is called before hook_node_access_records() in node_save(). */ function apachesolr_nodeaccess_node_insert($node){ $node->apachesolr_nodeaccess_ignore = 1; } /** * Implements hook_node_update(). */ function apachesolr_nodeaccess_node_update($node){ $node->apachesolr_nodeaccess_ignore = 1; } /** * Implements hook_node_access_records(). * * Listen to this hook to find out when a node needs to be re-indexed * for its node access grants. */ function apachesolr_nodeaccess_node_access_records($node) { // node_access_needs_rebuild() will usually be TRUE during a // full rebuild. if (empty($node->apachesolr_nodeaccess_ignore) && !node_access_needs_rebuild()) { // Only one node is being changed - mark for re-indexing. apachesolr_mark_node($node->nid); } } /** * Implements hook_form_alter(). */ function apachesolr_nodeaccess_form_alter(&$form, $form_state, $form_id) { if ($form_id == 'node_configure_rebuild_confirm') { $form['#submit'][] = 'apachesolr_nodeaccess_rebuild_nodeaccess'; } } /** * Force Solr to do a total re-index when node access rules change. * * This is unfortunate because not every node is going to be affected, but * there is little we can do. */ function apachesolr_nodeaccess_rebuild_nodeaccess(&$form, $form_state) { drupal_set_message(t('Solr search index will be rebuilt.')); apachesolr_clear_last_index(); } function apachesolr_nodeaccess_enable() { drupal_set_message(t('Your content must be re-indexed before Apache Solr node access will be functional on searches.', array('@url' => url('admin/settings/apachesolr/index'))), 'warning'); }