uid) { if (!isset($anonymous_account)) { // Load the anonymous user. $anonymous_account = drupal_anonymous_user(); } $original_user = $user; session_save_session(FALSE); $user = $anonymous_account; } if (!node_access('view', $node)) { // Get node access grants. $result = db_query('SELECT * FROM {node_access} WHERE (nid = 0 OR nid = %d) AND grant_view = 1', $node->nid); while ($grant = db_fetch_object($result)) { $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); } // Switch back the original user if (isset($original_user)) { $user = $original_user; session_save_session(TRUE); } } /** * 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 (empty($node_access_query)) { throw new Exception('No query object in apachesolr_nodeaccess'); } if (user_access('administer nodes', $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->uid); 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; } /** * Implementation of hook_apachesolr_modify_query(). */ function apachesolr_nodeaccess_apachesolr_modify_query(&$query, &$params) { global $user; try { $subquery = _apachesolr_nodeaccess_build_subquery($user); } catch (Exception $e) { $query = NULL; watchdog("apachesolr_nodeaccess", t('User %name (UID:!uid) cannot search: @message', array('%name' => $user->name, '!uid' => $user->uid, '@message' => $e->getMessage()))); return; } if (!empty($subquery)) { $query->add_subquery($subquery, 'OR'); } } /** * Implementation of hook_nodeapi(). * * Listen to this hook to find out when a node is being saved. */ function apachesolr_nodeaccess_nodeapi(&$node, $op) { switch ($op) { case 'insert': case 'update': // hook_nodeapi() is called before hook_node_access_records() in node_save(). $node->apachesolr_nodeaccess_ignore = 1; break; } } /** * Implementation of 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); } } /** * Implementation of hook_form_alter(). */ function apachesolr_nodeaccess_form_alter($form_id, &$form) { if ($form_id == 'node_configure_rebuild_confirm') { $form['#submit']['apachesolr_nodeaccess_rebuild_nodeaccess'] = array(); } } /** * 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_id, &$form) { drupal_set_message(t('Solr search index will be rebuilt.')); node_access_needs_rebuild(TRUE); 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'); }