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); } } /** * 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); 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, $caller = 'apachesolr_search') { if ($caller == 'apachesolr_views_query') { return; } global $user; try { $subquery = apachesolr_nodeaccess_build_subquery($user); } catch (Exception $e) { $query = NULL; watchdog("apachesolr_nodeaccess", '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, $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.')); 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'); }