Extract role-check into utility function authcache_diff_roles
[project/authcache.git] / authcache.admin.inc
1 <?php
2
3 /**
4 * @file
5 * Admin forms and pages.
6 */
7
8 /**
9 * Main Authcache configuration form
10 */
11
12 function authcache_admin_config($form, &$form_state) {
13 drupal_set_title(t('Authcache Configuration'));
14
15 $form['roles'] = array(
16 '#type' => 'fieldset',
17 '#title' => t('Authcache Roles'),
18 '#collapsible' => TRUE,
19 );
20 $form['roles']['authcache_roles'] = array(
21 '#title' => t('Enable caching for specified user roles'),
22 '#description' => t('If no roles are selected, Authcache page caching will not be enabled. Unchecked roles will never be cached.'),
23 '#type' => 'checkboxes',
24 '#options' => _authcache_get_roles(TRUE),
25 '#default_value' => variable_get('authcache_roles', array()),
26 );
27 $form['roles']['authcache_nojsroles'] = array(
28 '#title' => t('Enable caching without JavaScript'),
29 '#description' => t('Unchecked roles will not be cached if JavaScript is turned off in the users browser.'),
30 '#type' => 'checkboxes',
31 '#options' => _authcache_get_roles(TRUE),
32 '#default_value' => variable_get('authcache_nojsroles', drupal_map_assoc(array(DRUPAL_ANONYMOUS_RID))),
33 );
34
35 $form['adv'] = array(
36 '#type' => 'fieldset',
37 '#title' => t('Advanced'),
38 '#collapsible' => TRUE,
39 //'#collapsed' => (!variable_get('authcache_post', 0) && !variable_get('authcache_http200', 0) && !variable_get('authcache_noajax', 0)),
40 );
41 $form['adv']['noajax'] = array(
42 '#type' => 'checkbox',
43 '#title' => t("Don't cache Drupal Ajax requests"),
44 '#default_value' => variable_get('authcache_noajax', 0),
45 '#description' => t("Disable caching of Ajax requests, such as autocomplete."),
46 );
47 $form['adv']['http200'] = array(
48 '#type' => 'checkbox',
49 '#title' => t('Only cache HTTP 200 OK pages (exclude 404, 403, etc)'),
50 '#default_value' => variable_get('authcache_http200', 0),
51 '#description' => t("It's recommended to cache all Drupal pages, though error response pages can be excluded if required."),
52 );
53 $form['adv']['su'] = array(
54 '#type' => 'checkbox',
55 '#title' => t('Allow caching for superuser (uid = 1)'),
56 '#default_value' => variable_get('authcache_su', 0),
57 '#description' => t('Specify whether pages should also be cached for the superuser.'),
58 );
59 $form['adv']['mimetype'] = array(
60 '#type' => 'textarea',
61 '#title' => t('Cacheable content-types'),
62 '#description' => t('Specify which content-types can be cached.'),
63 '#default_value' => variable_get('authcache_mimetype', AUTHCACHE_MIMETYPE_DEFAULT),
64 );
65 $form['adv']['post'] = array(
66 '#type' => 'radios',
67 '#title' => t('Authcache Ajax Method (GET vs POST)'),
68 '#options' => array(
69 0 => 'Automatic',
70 1 => 'POST',
71 ),
72 '#default_value' => variable_get('authcache_post', 0),
73 '#description' => t('Automatic will use GET for the Authcache Ajax request and POST if the request is over 2,000 characters. You can explicitly require POST if needed, though GET is faster.'),
74 );
75
76 $form['submit'] = array(
77 '#type' => 'submit',
78 '#value' => t('Save & clear cached pages'),
79 );
80
81 //
82 // Status messages
83 //
84 if (!variable_get('cache_backends', NULL)) {
85 drupal_set_message(t('Your settings.php file must be modified to enable Authcache ($conf[\'cache_backends\']). See <a href="@url">README.txt</a>.', array('@url' => base_path() . drupal_get_path('module', 'authcache') . '/README.txt')), 'error');
86 }
87
88 if (!variable_get('page_compression', TRUE)) {
89 drupal_set_message(t('Note: Page compression is not enabled! It is strongly recommend that you <a href="./../performance">turn this setting on</a> through Drupal to allow for faster page response times.'), 'warning');
90 }
91
92 return $form;
93 }
94
95
96 /**
97 * Authcache config form submit
98 */
99 function authcache_admin_config_validate($form, &$form_state) {
100
101 }
102
103 /**
104 * Authcache config form submit
105 */
106 function authcache_admin_config_submit($form, &$form_state) {
107 global $user;
108
109 // Roles
110 $cache_roles = drupal_map_assoc(array_filter($form_state['values']['authcache_roles']));
111 $nojs_roles = drupal_map_assoc(array_filter($form_state['values']['authcache_nojsroles']));
112
113 // Define/update page caching settings if needed
114 $pagecaching = variable_get('authcache_pagecaching', FALSE);
115
116 // Not defined, first config submit
117 if (!$pagecaching) {
118 variable_set('authcache_pagecaching', array(array(
119 'option' => 0,
120 'pages' => AUTHCACHE_NOCACHE_DEFAULT,
121 'noadmin' => 1,
122 'roles' => $cache_roles,
123 )));
124 }
125 // User may have added new role; apply new roles to first page ruleset, just to be safe
126 elseif ($cache_roles != variable_get('authcache_roles', $cache_roles)) {
127 $pagecaching[0]['roles'] = $cache_roles;
128 variable_set('authcache_pagecaching', $pagecaching);
129 }
130
131 // Forcibly disable Drupal's built-in SQL caching (no need to cache page twice for anonymous users!)
132 if (in_array(DRUPAL_ANONYMOUS_RID, $cache_roles) && variable_get('cache', 0) != 0) {
133 variable_set('cache', 0);
134 drupal_set_message(t("Drupal's built-in page caching for anonymous users has been disabled to avoid redundant caching."));
135 }
136
137 // Devel query logging
138 // variable_set('dev_query', $form_state['values']['dev_query']);
139
140
141 // Delete variable if not in use
142 foreach (array('post', 'http200', 'su', 'noajax', 'mimetype') as $key) {
143 if ($value = $form_state['values'][$key]) {
144 variable_set("authcache_{$key}", $value);
145 }
146 else {
147 variable_del("authcache_{$key}");
148 }
149 }
150
151 variable_set('authcache_roles', $cache_roles);
152 variable_set('authcache_nojsroles', $nojs_roles);
153
154 drupal_set_message(t('Your Authcache settings have been saved.'));
155
156 cache_clear_all('*', 'cache_page', TRUE);
157 drupal_set_message(t('Cached pages cleared.'));
158 }
159
160
161 /**
162 * Add new page caching rule to form (part of ajax)
163 */
164 function _authcache_pagecache_form($details) {
165 $form['#tree'] = TRUE;
166 $delta = $details['delta'];
167
168 $roles = user_roles();
169 $roles[DRUPAL_AUTHENTICATED_RID] .= ' ' . t('(without additional roles)');
170
171 // Cacheability settings
172 $options = array(t('Cache every page except the listed pages.'), t('Cache only the listed pages.'));
173 $description = t("To delete this ruleset, leave the textbox empty.") . ' ' . t("Enter one page per line as Drupal paths. The '*' character is a wildcard. Example paths are '%blog' for the blog page and %blog-wildcard for every personal blog. %front is the front page.", array('%blog' => 'blog', '%blog-wildcard' => 'blog/*', '%front' => '<front>'));
174 if (user_access('use PHP for settings')) {
175 $options[] = t('Cache pages for which the following PHP code returns <code>TRUE</code> (PHP-mode, experts only).');
176 $description .= t('If the PHP-mode is chosen, enter PHP code between %php. Note that executing incorrect PHP-code can severely break your Drupal site.', array('%php' => '<?php ?>'));
177 }
178 $form['fieldset'] = array(
179 '#type' => 'fieldset',
180 '#title' => t('Caching Ruleset # %delta', array('%delta' => $delta + 1)),
181 '#collapsible' => TRUE,
182 );
183 $form['fieldset']['option'] = array(
184 '#type' => 'radios',
185 '#title' => t('Cache specified pages'),
186 '#options' => $options,
187 '#default_value' => $details['option'],
188 );
189
190 $form['fieldset']['pages'] = array(
191 '#type' => 'textarea',
192 '#title' => t('Pages'),
193 '#description' => $description,
194 '#default_value' => $details['pages'],
195 );
196 $form['fieldset']['noadmin'] = array(
197 '#type' => 'checkbox',
198 '#title' => t('Exclude Admin pages'),
199 '#description' => t('Do not cache administrative pages.'),
200 '#default_value' => $details['noadmin'],
201 );
202 $form['fieldset']['roles'] = array(
203 '#title' => 'Apply to these roles',
204 '#type' => 'checkboxes',
205 '#options' => _authcache_get_roles(),
206 '#default_value' => (is_array($details['roles'])) ? $details['roles'] : array(),
207 );
208
209 return $form;
210
211 }
212
213 /**
214 * Page caching rules form
215 */
216 function authcache_admin_pagecaching($form, $form_state, $ajax_form = array()) {
217 drupal_set_title(t('Authcache Page Caching Settings'));
218 drupal_add_css(drupal_get_path('module', 'authcache') . '/authcache.css');
219
220 if (!count(variable_get('authcache_roles', array()))) {
221 drupal_set_message(t('You must first select roles to cache before defining page caching setting.'), 'error');
222 return $form;
223 }
224
225 $form['#cache'] = TRUE;
226
227 // The contents of ajax_form will either come from the db or from $form_state
228 if (isset($form_state['ajax_form'])) {
229 $ajax_form = $form_state['ajax_form'] + (array) $ajax_form;
230 }
231
232 // Default values
233 if (empty($ajax_form)) {
234 $ajax_form['ajax_form'] = variable_get('authcache_pagecaching', array(array()));
235 }
236
237 $form['ajax_wrapper'] = array(
238 '#tree' => FALSE,
239 '#prefix' => '<div class="clear-block" id="ajax-wrapper">',
240 '#suffix' => '</div>',
241 );
242
243 $form['ajax_wrapper']['ajax']['#tree'] = TRUE;
244
245
246 foreach ($ajax_form['ajax_form'] as $delta => $details) {
247 $details = (isset($details['fieldset'])) ? $details['fieldset'] : $details; // fieldset inserted from ajax postback
248 $details['delta'] = $delta;
249
250 $form['ajax_wrapper']['ajax'][$delta] = _authcache_pagecache_form($details);
251 }
252
253 // ajax-enabled "Add" button
254 $form['authcache_add_cache'] = array(
255 '#type' => 'submit',
256 '#value' => t('Add new ruleset') . '...',
257 '#description' => t("If the above ruleset isn't, click here to add more choices."),
258 '#submit' => array('authcache_ajax_add'),
259 '#ajax' => array(
260 'callback' => 'authcache_ajax_add',
261 'wrapper' => 'ajax-wrapper',
262 'method' => 'replace',
263 'effect' => 'fade',
264 ),
265 '#attributes' => array('class' => array('authcache-add')),
266 '#attached' => array('css' => array(
267 drupal_get_path('module', 'authcache') . '/authcache.admin.css',
268 )),
269 );
270
271 $form['submit'] = array(
272 '#type' => 'submit',
273 '#value' => t('Save & clear cached pages'),
274 '#prefix' => '<br><hr size="1"><br>',
275 );
276
277 return $form;
278 }
279
280 /**
281 * Page caching rules form submit
282 */
283 function authcache_admin_pagecaching_submit($form, &$form_state) {
284
285 // Ignore ajax events
286 if ($form_state['clicked_button']['#id'] == 'edit-submit') {
287 $pagecaching = array();
288
289 foreach ($form_state['values']['ajax'] as $key => $ray) {
290 $values = $ray['fieldset'];
291 $values['roles'] = drupal_map_assoc(array_filter($values['roles']));
292 if ($values['pages']) {
293 $pagecaching[$key] = $values;
294 }
295 if (empty($values['roles'])) {
296 drupal_set_message(t('Ruleset #%key is disabled since no roles are associated with it.', array('%key' => ($key + 1))), 'warning');
297 }
298 }
299
300 if (!empty($pagecaching)) {
301 variable_set('authcache_pagecaching', $pagecaching);
302 }
303 else {
304 variable_set('authcache_pagecaching', array(
305 array(
306 'option' => 0,
307 'pages' => AUTHCACHE_NOCACHE_DEFAULT,
308 'noadmin' => 1,
309 'roles' => variable_get('authcache_roles', array()),
310 ),
311 )
312 );
313 }
314
315 drupal_set_message(t('Your page caching settings have been saved.'));
316 cache_clear_all();
317 drupal_set_message(t('Cached pages cleared.'));
318
319 }
320 }
321
322
323 /**
324 * Generic ajax menu callback (['#ajax']['path'])
325 */
326 function authcache_ajax() {
327 $form_state = array(
328 'storage' => NULL,
329 'submitted' => FALSE,
330 );
331 $form_build_id = $_POST['form_build_id'];
332 $form = form_get_cache($form_build_id, $form_state);
333 $args = $form['#parameters'];
334 $form_id = array_shift($args);
335 $form['#post'] = $form_state['post'] = $_POST;
336 $form_state['#redirect'] = $form['#programmed'] = FALSE;
337 drupal_process_form($form_id, $form, $form_state);
338 $form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
339 $ajax_form = $form['ajax_wrapper']['ajax'];
340 unset($ajax_form['#prefix'], $ajax_form['#suffix']); // Prevent duplicate wrappers.
341 // TODO Please change this theme call to use an associative array for the $variables parameter.
342 // TODO Please change this theme call to use an associative array for the $variables parameter.
343 drupal_json_output(array(
344 'status' => TRUE,
345 'data' => theme('status_messages') . drupal_render($ajax_form),
346 ));
347 }
348
349 /**
350 * Generic ajax add
351 */
352 function authcache_ajax_add($form, &$form_state) {
353 if (isset($form_state['values']['ajax'])) {
354 $ajax_form['ajax_form'] = $form_state['values']['ajax'];
355 }
356
357 $ajax_form['ajax_form'][] = array();
358
359 unset($form_state['submit_handlers']);
360 form_execute_handlers('submit', $form, $form_state);
361 $form_state['ajax_form'] = $ajax_form;
362 $form_state['rebuild'] = TRUE;
363 return $form;
364 }
365
366 /**
367 * Helper function, get authcache user roles
368 * @param $all_roles = return all user roles
369 * @return array of user roles
370 */
371 function _authcache_get_roles($all_roles = FALSE) {
372 $roles = user_roles();
373 $roles[DRUPAL_AUTHENTICATED_RID] .= ' ' . t('(without additional roles)');
374 if ($all_roles) {
375 return $roles;
376 }
377 else {
378 $authcache_roles = array();
379 foreach (variable_get('authcache_roles', array()) as $key) {
380 $authcache_roles[$key] = $roles[$key];
381 }
382 return $authcache_roles;
383 }
384 }