Mercurial > hg > MPIWG-drupal-modules
comparison sites/all/modules/custom/solrconnect/apachesolr_access/apachesolr_access.module @ 0:015d06b10d37 default tip
initial
author | dwinter |
---|---|
date | Wed, 31 Jul 2013 13:49:13 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:015d06b10d37 |
---|---|
1 <?php | |
2 | |
3 /** | |
4 * Implements hook_apachesolr_index_document_build_node() | |
5 * | |
6 * Add node access grants of generic view grants if node access is not used. | |
7 * | |
8 * @param $document | |
9 * The document to add our node access information to | |
10 * @param $node | |
11 * The node which is used to built the document from | |
12 * @param $env_id | |
13 * The environment for which we are building the document. This parameter does not have any effect in | |
14 * this code so it can be ignored | |
15 */ | |
16 function apachesolr_access_apachesolr_index_document_build_node(ApacheSolrDocument $document, $node, $env_id) { | |
17 $account = &drupal_static(__FUNCTION__); | |
18 | |
19 if (!isset($account)) { | |
20 // Load the anonymous user. | |
21 $account = drupal_anonymous_user(); | |
22 } | |
23 | |
24 // When using a node access module like Domain Access which has | |
25 // access grants that vary for anonymous users for the same content, | |
26 // this variable should be set to 1. Note that doing so will prevent | |
27 // any results from being returned if using apachesolr_multisitesearch | |
28 // from a different site. | |
29 $always_add = apachesolr_environment_variable_get($env_id, 'apachesolr_access_always_add_grants', 0); | |
30 if ($always_add || !node_access('view', $node, $account)) { | |
31 // Get node access grants. | |
32 $result = db_query('SELECT * FROM {node_access} WHERE (nid = 0 OR nid = :nid) AND grant_view = 1', array(':nid' => $node->nid)); | |
33 foreach ($result as $grant) { | |
34 $grant_realm = apachesolr_access_clean_realm_name($grant->realm); | |
35 $key = 'access_node_' . apachesolr_site_hash() . '_' . $grant_realm; | |
36 $document->addField($key, $grant->gid); | |
37 } | |
38 } | |
39 else { | |
40 // Add the generic view grant if we are not using | |
41 // node access or the node is viewable by anonymous users. | |
42 // We assume we'll never have an entity with the name '__all'. | |
43 $document->addField('access__all', 0); | |
44 } | |
45 } | |
46 | |
47 /** | |
48 * Creates a Solr query for a given user | |
49 * | |
50 * @param $account | |
51 * an account to get grants for and build a solr query | |
52 * | |
53 * @throws Exception | |
54 * | |
55 * @return SolrFilterSubQuery | |
56 * Instance of SolrFilterSubQuery | |
57 */ | |
58 function apachesolr_access_build_subquery($account) { | |
59 if (!user_access('access content', $account)) { | |
60 throw new Exception('No access'); | |
61 } | |
62 $node_access_query = apachesolr_drupal_subquery(); | |
63 if (user_access('bypass node access', $account)) { | |
64 // Access all content from the current site. | |
65 $node_access_query->addFilter('hash', apachesolr_site_hash()); | |
66 } | |
67 else { | |
68 // Get node access grants. | |
69 $grants = node_access_grants('view', $account); | |
70 foreach ($grants as $realm => $gids) { | |
71 $realm = apachesolr_access_clean_realm_name($realm); | |
72 foreach ($gids as $gid) { | |
73 $node_access_query->addFilter('access_node_' . apachesolr_site_hash() . '_' . $realm, $gid); | |
74 } | |
75 } | |
76 } | |
77 // Everyone can access public content. Note that if the variable | |
78 // 'apachesolr_access_always_add_grants' is TRUE, no content from this site | |
79 // is considered "public". However, this condition may match documents in | |
80 // the Solr index supplied by other sites when multiple sites are indexing | |
81 // into the same index , i.e. multisite search. | |
82 $node_access_query->addFilter('access__all', 0); | |
83 return $node_access_query; | |
84 } | |
85 | |
86 /** | |
87 * Implements hook_apachesolr_query_alter(). | |
88 * | |
89 * Alter the query to include the access subquery | |
90 * | |
91 * @param DrupalSolrQueryInterface $query | |
92 * | |
93 */ | |
94 function apachesolr_access_apachesolr_query_alter(DrupalSolrQueryInterface $query) { | |
95 global $user; | |
96 try { | |
97 $subquery = apachesolr_access_build_subquery($user); | |
98 $query->addFilterSubQuery($subquery); | |
99 } | |
100 catch (Exception $e) { | |
101 watchdog("apachesolr_access", 'User %name (UID:!uid) cannot search: @message', array('%name' => $user->name, '!uid' => $user->uid, '@message' => $e->getMessage())); | |
102 $query->abort_search = TRUE; | |
103 } | |
104 } | |
105 | |
106 /** | |
107 * Implements hook_node_insert(). | |
108 * | |
109 * hook_node_ACTION() is called before hook_node_access_records() in node_save(). | |
110 * | |
111 * @param object $node | |
112 */ | |
113 function apachesolr_access_node_insert($node) { | |
114 $node->apachesolr_access_node_ignore = 1; | |
115 } | |
116 | |
117 /** | |
118 * Implements hook_node_update(). | |
119 * | |
120 * hook_node_ACTION() is called before hook_node_access_records() in node_save(). | |
121 * | |
122 * @param object $node | |
123 */ | |
124 function apachesolr_access_node_update($node) { | |
125 $node->apachesolr_access_node_ignore = 1; | |
126 } | |
127 | |
128 /** | |
129 * Implements hook_node_access_records(). | |
130 * | |
131 * Listen to this hook to find out when a node needs to be re-indexed | |
132 * for its node access grants. | |
133 * | |
134 * @param object $node | |
135 */ | |
136 function apachesolr_access_node_access_records($node) { | |
137 // node_access_needs_rebuild() will usually be TRUE during a | |
138 // full rebuild. | |
139 if (empty($node->apachesolr_access_node_ignore) && !node_access_needs_rebuild()) { | |
140 // Only one node is being changed - mark for re-indexing. | |
141 apachesolr_mark_entity('node', $node->nid); | |
142 } | |
143 } | |
144 | |
145 /** | |
146 * Implements hook_form_alter(). | |
147 * | |
148 * @param array $form | |
149 * @param array $form_state | |
150 * @param string $form_id | |
151 * | |
152 */ | |
153 function apachesolr_access_form_alter(&$form, $form_state, $form_id) { | |
154 $form['#submit'][] = 'apachesolr_access_rebuild_nodeaccess'; | |
155 } | |
156 | |
157 /** | |
158 * Implements hook_form_FORM_ID_alter(). | |
159 */ | |
160 function apachesolr_access_form_apachesolr_environment_edit_form_alter(&$form, $form_state) { | |
161 $form['conf']['apachesolr_access_always_add_grants'] = array( | |
162 '#type' => 'checkbox', | |
163 '#title' => t('Add access grants even for public content'), | |
164 '#default_value' => empty($form['#environment']['conf']['apachesolr_access_always_add_grants']) ? 0 : 1, | |
165 '#description' => t('Normally should be disabled. Changing this value requires all content to be re-indexed. Useful for sites using Domamin Access or simliar node acess modules with grants that vary for anonymous users.'), | |
166 ); | |
167 $form['actions']['save']['#submit'][] = 'apachesolr_access_environment_edit_form_submit'; | |
168 $form['actions']['save_edit']['#submit'][] = 'apachesolr_access_environment_edit_form_submit'; | |
169 } | |
170 | |
171 /** | |
172 * Added button-level form submit function for apachesolr_environment_edit_form. | |
173 */ | |
174 function apachesolr_access_environment_edit_form_submit($form, &$form_state) { | |
175 $prior = empty($form['#environment']['conf']['apachesolr_access_always_add_grants']) ? 0 : 1; | |
176 if ($form_state['values']['conf']['apachesolr_access_always_add_grants'] != $prior) { | |
177 apachesolr_access_enable(); | |
178 } | |
179 } | |
180 | |
181 /** | |
182 * Force Solr to do a total re-index when node access rules change. | |
183 * | |
184 * This is unfortunate because not every node is going to be affected, but | |
185 * there is little we can do. | |
186 * | |
187 * @param $form | |
188 * @param $form_state | |
189 * | |
190 */ | |
191 function apachesolr_access_rebuild_nodeaccess($form, $form_state) { | |
192 drupal_set_message(t('Solr search index will be rebuilt.')); | |
193 // Clear last updated | |
194 apachesolr_clear_last_index_position(); | |
195 } | |
196 | |
197 /** | |
198 * Implements hook_enable(). | |
199 * | |
200 * On enabling the module, tell the user to reindex | |
201 */ | |
202 function apachesolr_access_enable() { | |
203 drupal_set_message(t('Your content <a href="@url">must be re-indexed</a> before Apache Solr Access will be functional on searches.', array('@url' => url('admin/config/search/apachesolr/index'))), 'warning'); | |
204 } | |
205 | |
206 /** | |
207 * Helper function - return a safe (PHP identifier) realm name. | |
208 * | |
209 * @todo See if we can replace this with a native php function | |
210 * | |
211 * @param string $realm | |
212 * | |
213 * @return string | |
214 * Clean string without bad characters | |
215 */ | |
216 function apachesolr_access_clean_realm_name($realm) { | |
217 return preg_replace('/[^a-zA-Z0-9_\x7f-\xff]/', '_', $realm); | |
218 } |