View source
<?php
define('AUTHCACHE_NOCACHE_DEFAULT', '
user*
node/add/*
node/*/edit
node/*/track
tracker*
civicrm*
cart*
checkout*
system/files/*
system/temporary*
file/ajax/*
js/admin_menu/cache/*
');
define('AUTHCACHE_MIMETYPE_DEFAULT', '
text/html
text/javascript
text/plain
application/xml
application/atom+xml
');
require_once __DIR__ . '/authcache.cache.inc';
function authcache_menu() {
$items['admin/config/system/authcache'] = array(
'title' => 'Authcache',
'description' => 'Configure authenticated user page caching.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'authcache_admin_config',
),
'access arguments' => array(
'administer site configuration',
),
'file' => 'authcache.admin.inc',
'weight' => 10,
);
$items['admin/config/system/authcache/config'] = array(
'title' => 'Configuration',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['admin/config/system/authcache/pagecaching'] = array(
'title' => 'Page caching settings',
'description' => "Configure page cache settings.",
'page callback' => 'drupal_get_form',
'page arguments' => array(
'authcache_admin_pagecaching',
),
'access arguments' => array(
'administer site configuration',
),
'file' => 'authcache.admin.inc',
'type' => MENU_LOCAL_TASK,
'weight' => 20,
);
return $items;
}
function authcache_module_implements_alter(&$implementations, $hook) {
if ($hook === 'init') {
$me = $implementations['authcache'];
unset($implementations['authcache']);
$implementations = array_merge(array(
'authcache' => $me,
), $implementations);
}
if ($hook === 'exit') {
$me = $implementations['authcache'];
unset($implementations['authcache']);
$implementations['authcache'] = $me;
}
}
function authcache_init() {
global $conf, $user;
$reasons = module_invoke_all('authcache_request_exclude');
if (!empty($reasons)) {
_authcache_exclude(reset($reasons));
}
$reasons = module_invoke_all('authcache_account_exclude', $user);
if (!empty($reasons)) {
_authcache_exclude(reset($reasons));
}
if (!authcache_excluded()) {
$conf['configurable_timezones'] = FALSE;
}
drupal_add_library('system', 'jquery.cookie');
drupal_add_js(drupal_get_path('module', 'authcache') . '/authcache.js');
drupal_add_js(array(
'authcache' => array(
'q' => $_GET['q'],
'cp' => array(
'path' => ini_get('session.cookie_path'),
'domain' => ini_get('session.cookie_domain'),
'secure' => ini_get('session.cookie_secure') == '1',
),
'cl' => max(1, (int) authcache_key_lifetime() / 86400),
),
), 'setting');
if (!authcache_excluded()) {
_authcache_original_ob_level(TRUE);
}
}
function authcache_exit($destination = NULL) {
global $user;
if (drupal_get_bootstrap_phase() < DRUPAL_BOOTSTRAP_FULL) {
return;
}
if ($destination !== NULL) {
authcache_cancel(t('Redirecting to @destination', array(
'@destination' => $destination,
)));
}
$reasons = module_invoke_all('authcache_preclude');
if (!empty($reasons)) {
_authcache_preclude(reset($reasons));
}
$authcache_key = authcache_key();
if ($authcache_key !== authcache_backend_initial_key()) {
$has_session = !empty($user->uid) || !empty($_SESSION);
$lifetime = authcache_key_lifetime();
module_invoke_all('authcache_backend_key_set', $authcache_key, $lifetime, $has_session);
}
if (!drupal_is_cli() && !headers_sent()) {
authcache_fix_cookies();
}
drupal_page_is_cacheable(FALSE);
if (authcache_excluded()) {
return;
}
$reasons = module_invoke_all('authcache_cancel');
if (!empty($reasons)) {
authcache_cancel(reset($reasons));
}
if (authcache_page_is_cacheable()) {
$cache = authcache_backend_cache_save();
authcache_serve_page_from_cache($cache, authcache_key());
}
}
function authcache_flush_caches() {
return array(
'cache_authcache_key',
);
}
function authcache_form_alter(&$form, &$form_state, $form_id) {
global $user;
if (authcache_page_is_cacheable()) {
if (empty($form['#after_build'])) {
$form['#after_build'] = array(
'_authcache_default_form_after_build',
);
}
else {
array_unshift($form['#after_build'], '_authcache_default_form_after_build');
}
if ($user->uid && !empty($form['form_build_id'])) {
authcache_element_suspect($form['form_build_id'], t('Form requiring the form cache on the page. Enable authcache_form or implement custom code capable of handling cached forms.'));
}
if (!empty($form['form_token'])) {
authcache_element_suspect($form['form_token'], t('Form with CSRF protection on page. Enable authcache_form or implement custom code capable of handling CSRF protected forms.'));
}
authcache_form_value_suspect($form, $form_id);
}
switch ($form_id) {
case 'user_profile_form':
if (authcache_account_allows_caching()) {
unset($form['timezone']);
}
break;
case 'contact_site_form':
case 'contact_personal_form':
if ($user->uid && authcache_page_is_cacheable()) {
unset($form['name']['#default_value']);
unset($form['mail']['#default_value']);
}
break;
}
}
function authcache_form_comment_form_alter(&$form, &$form_state) {
global $user;
if ($user->uid && authcache_page_is_cacheable() && !$form_state['comment']->cid) {
$message = t('User name on comment form. Enable Authcache Comment module or implement custom code capable of retrieving/removing the user name.');
if (isset($form['author']['name']['#type']) && $form['author']['name']['#type'] === 'value') {
authcache_element_suspect($form['author']['name'], $message);
}
if (isset($form['author']['_author'])) {
authcache_element_suspect($form['author']['_author'], $message);
}
}
}
function authcache_form_system_performance_settings_alter(&$form, &$form_state) {
$roles = authcache_get_roles();
if (count($roles)) {
$message = '<p>' . t('Drupal core page caching for anonymous users does not work properly when Authcache is enabled. Please either deactivate Drupal core page caching or disable Authcache.') . '</p>';
if (!isset($roles[DRUPAL_ANONYMOUS_RID])) {
$message .= '<p>' . t('You may enable the page cache for anonymous users by <a href="!link">configuring</a> Authcache for anonymous users', array(
'!link' => url('admin/config/system/authcache'),
)) . '</p>';
}
if (variable_get('page_cache_without_database')) {
$message .= '<p>' . t('Furthermore it seems that !setting is enabled. Please remove that line from !file, otherwise Authcache will not work properly.', array(
'!setting' => '<code>$conf[\'page_cache_without_database\']</code>',
'!file' => '<code>' . conf_path() . '/settings.php</code>',
)) . '</p>';
}
$form['caching']['authcache-warning'] = array(
'#type' => 'container',
'#attributes' => array(
'class' => array(
'messages',
'warning',
),
),
'message' => array(
'#markup' => $message,
),
'#weight' => -3,
);
if (!variable_get('page_cache_without_database')) {
$form['caching']['authcache-warning']['#states'] = array(
'visible' => array(
':input[name=cache]' => array(
'checked' => TRUE,
),
),
);
}
unset($form['bandwidth_optimization']['page_compression']['#prefix']);
unset($form['bandwidth_optimization']['page_compression']['#suffix']);
}
}
function authcache_form_value_suspect(&$element, $form_id, $parents = array()) {
if (isset($element['#type']) && $element['#type'] === 'value') {
$name = '';
$num_parents = count($parents);
if (isset($element['#name'])) {
$name = $element['#name'];
}
elseif ($num_parents > 0) {
$name = $parents[0];
if ($num_parents > 1) {
$name .= '[' . implode('][', array_slice($parents, 1)) . ']';
}
}
authcache_element_suspect($element, t('Value element %name contained in the cacheable form %form_id. Please enable a suitable Authcache integration module for that form or file a support request.', array(
'%name' => $name,
'%form_id' => $form_id,
)));
}
foreach (element_children($element, FALSE) as $key) {
authcache_form_value_suspect($element[$key], $form_id, array_merge($parents, array(
$key,
)));
}
}
function authcache_form_value_set_cacheable(&$element) {
if (isset($element['#type']) && $element['#type'] === 'value') {
authcache_element_set_cacheable($element);
}
foreach (element_children($element, FALSE) as $key) {
authcache_form_value_set_cacheable($element[$key]);
}
}
function _authcache_default_form_after_build($form, $form_state) {
global $user;
if (authcache_page_is_cacheable()) {
if (empty($form_state['rebuild']) && empty($form_state['cache'])) {
$form_state['no_cache'] = TRUE;
unset($form['form_build_id']);
unset($form['#build_id']);
authcache_form_value_set_cacheable($form);
}
}
return $form;
}
function authcache_preprocess(&$variables, $hook) {
$variables['authcache_is_cacheable'] = authcache_page_is_cacheable();
}
function authcache_preprocess_page(&$variables) {
global $user;
if (authcache_page_is_cacheable()) {
authcache_element_suspect($variables['tabs'], t('Tabs on page. Enable authcache_menu or implement custom code capable of detecting when caching tabs is acceptable.'));
authcache_element_suspect($variables['action_links'], t('Action links on page. Enable authcache_menu or implement custom code capable of detecting when caching local actions is acceptable.'));
if (!$user->uid) {
authcache_element_set_cacheable($variables['tabs']);
authcache_element_set_cacheable($variables['action_links']);
}
}
}
function authcache_process_page(&$variables) {
if (!empty($variables['messages']) && authcache_page_is_cacheable()) {
authcache_cancel(t('Status message on page'));
}
}
function authcache_preprocess_toolbar(&$variables) {
if (isset($variables['toolbar']['toolbar_user']['#links']['account'])) {
$message = t('User name in toolbar. Enable Authcache User module or implement custom code capable of retrieving the user name.');
authcache_element_suspect($variables['toolbar']['toolbar_user'], $message);
}
foreach (element_children($variables['toolbar']['toolbar_drawer']) as $key) {
if (isset($variables['toolbar']['toolbar_drawer'][$key]['shortcuts']) && function_exists('shortcut_set_switch_access') && shortcut_set_switch_access()) {
$message = t('Switchable shortcut set in toolbar. Enable Authcache Menu or implement custom code capable of detecting when caching shortcuts is acceptable.');
authcache_element_suspect($variables['toolbar']['toolbar_drawer'][$key]['shortcuts'], $message);
}
}
}
function authcache_element_suspect(&$element, $message = NULL, $strict = FALSE) {
$element['#post_render'][] = 'authcache_ensure_element_cacheable';
if ($message) {
$element['#authcache_cancel_message'] = $message;
}
if ($strict || isset($element['#type']) && $element['#type'] === 'value') {
$element['#authcache_cancel_strict'] = TRUE;
}
}
function authcache_element_set_cacheable(&$element, $cacheable = TRUE) {
$element['#authcache_is_cacheable'] = $cacheable;
}
function authcache_element_is_cacheable($element) {
return !empty($element['#authcache_is_cacheable']);
}
function authcache_ensure_element_cacheable($markup, $element) {
$strict = !empty($element['#authcache_cancel_strict']);
if (($strict || !empty($markup)) && !authcache_element_is_cacheable($element)) {
$message = !empty($element['#authcache_cancel_message']) ? $element['#authcache_cancel_message'] : t('Non cacheable render element on page');
authcache_cancel($message);
}
return $markup;
}
function _authcache_exclude($reason = NULL) {
$excluded =& drupal_static(__FUNCTION__, FALSE);
if (!$excluded && !empty($reason)) {
$excluded = TRUE;
module_invoke_all('authcache_excluded', $reason);
}
return $excluded;
}
function authcache_excluded() {
return _authcache_exclude();
}
function authcache_cancel($reason = NULL) {
$canceled =& drupal_static(__FUNCTION__, FALSE);
if (!$canceled && !empty($reason)) {
$canceled = TRUE;
module_invoke_all('authcache_canceled', $reason);
}
return $canceled;
}
function authcache_canceled() {
return authcache_cancel();
}
function _authcache_preclude($reason = NULL) {
$precluded =& drupal_static(__FUNCTION__, FALSE);
if (!$precluded && !empty($reason)) {
$precluded = TRUE;
module_invoke_all('authcache_precluded', $reason);
}
return $precluded;
}
function authcache_precluded() {
return _authcache_preclude();
}
function authcache_page_is_cacheable() {
return !(authcache_excluded() || authcache_canceled());
}
function authcache_account_allows_caching($account = NULL) {
global $user;
$cacheable =& drupal_static(__FUNCTION__);
if (!isset($account)) {
$account = $user;
}
if (!isset($cacheable[$account->uid])) {
$reasons = module_invoke_all('authcache_account_exclude', $account);
$cacheable[$account->uid] = empty($reasons);
}
return $cacheable[$account->uid];
}
function authcache_key_properties() {
$properties =& drupal_static(__FUNCTION__);
if (!isset($properties)) {
$properties = module_invoke_all('authcache_key_properties');
drupal_alter('authcache_key_properties', $properties);
}
return $properties;
}
function authcache_user_key($properties, $superuser = FALSE) {
ksort($properties);
$data = serialize($properties);
$hmac = hash_hmac('sha1', $data, drupal_get_private_key(), FALSE);
if ($superuser) {
$hmac = hash_hmac('sha1', $hmac . $data, drupal_get_private_key(), FALSE);
}
$abbrev = variable_get('authcache_key_abbrev', 7);
return $abbrev ? substr($hmac, 0, $abbrev) : $hmac;
}
function authcache_key() {
global $user;
if ($user->uid) {
$key = authcache_user_key(authcache_key_properties(), $user->uid == 1);
}
else {
$key = authcache_backend_anonymous_key();
}
return $key;
}
function authcache_key_lifetime() {
$lifetime = (int) variable_get('authcache_key_lifetime', ini_get('session.cookie_lifetime'));
return $lifetime > 0 ? $lifetime : 0;
}
function authcache_fix_cookies($account = NULL) {
global $user;
if (!isset($account)) {
$account = $user;
}
$cookies = module_invoke_all('authcache_cookie', $account) + authcache_add_cookie();
drupal_alter('authcache_cookie', $cookies, $account);
$default_params = array(
'present' => FALSE,
'value' => NULL,
'lifetime' => authcache_key_lifetime(),
'path' => ini_get('session.cookie_path'),
'domain' => ini_get('session.cookie_domain'),
'secure' => ini_get('session.cookie_secure') == '1',
'httponly' => FALSE,
'samesite' => NULL,
);
foreach ($cookies as $name => $params) {
$params += $default_params;
$cookiename = str_replace('.', '_', $name);
$expires = NULL;
$value = NULL;
if ($params['present']) {
if (!isset($_COOKIE[$cookiename]) || $_COOKIE[$cookiename] != $params['value']) {
$expires = $params['lifetime'] ? REQUEST_TIME + $params['lifetime'] : 0;
$value = $params['value'];
}
}
elseif (!$params['present'] && isset($_COOKIE[$cookiename])) {
$expires = REQUEST_TIME - 86400;
$value = "";
}
if (isset($expires) && isset($value)) {
if (function_exists('drupal_setcookie')) {
$options = $params;
$options['expires'] = $expires;
unset($options['present']);
unset($options['value']);
unset($options['lifetime']);
drupal_setcookie($name, $value, $options);
}
else {
$options = $params;
setcookie($name, $value, $expires, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
}
}
}
}
function authcache_add_cookie($new_cookies = array()) {
$cookies =& drupal_static(__FUNCTION__, array());
$cookies = $new_cookies + $cookies;
return $cookies;
}
function authcache_diff_roles($account_roles, $allowed_roles) {
if (array_keys($account_roles) !== array(
DRUPAL_AUTHENTICATED_RID,
)) {
unset($account_roles[DRUPAL_AUTHENTICATED_RID]);
}
return array_diff_key($account_roles, $allowed_roles);
}
function authcache_get_roles($all_roles = FALSE) {
$roles = user_roles();
$roles[DRUPAL_AUTHENTICATED_RID] = t('@authenticated_user (without additional roles)', array(
'@authenticated_user' => $roles[DRUPAL_AUTHENTICATED_RID],
));
if (!$all_roles) {
$authcache_roles = variable_get('authcache_roles', array());
$roles = array_intersect_key($roles, $authcache_roles);
}
return $roles;
}
function authcache_get_content_type($header = NULL) {
if (!isset($header)) {
$header = drupal_get_http_header('content-type');
}
$params = explode(';', $header);
$params = array_map('trim', $params);
$mime = array_shift($params);
return array(
'mimetype' => $mime,
'params' => $params,
);
}
function _authcache_get_http_status($status = 200) {
$value = drupal_get_http_header('status');
return isset($value) ? (int) $value : $status;
}
function _authcache_default_pagecaching() {
return array(
array(
'option' => 0,
'pages' => AUTHCACHE_NOCACHE_DEFAULT,
'noadmin' => 1,
'roles' => array(
'custom' => TRUE,
'roles' => drupal_map_assoc(array(
DRUPAL_ANONYMOUS_RID,
DRUPAL_AUTHENTICATED_RID,
)),
),
),
);
}
function _authcache_original_ob_level($set = FALSE) {
$original_ob_level =& drupal_static(__FUNCTION__);
if ($set) {
$original_ob_level = ob_get_level();
}
return $original_ob_level;
}
function authcache_authcache_key_properties() {
global $user, $base_root;
$account_roles = $user->roles;
if (array_keys($account_roles) !== array(
DRUPAL_AUTHENTICATED_RID,
)) {
unset($account_roles[DRUPAL_AUTHENTICATED_RID]);
}
$roles = array_keys($account_roles);
sort($roles);
return array(
'base_root' => $base_root,
'roles' => $roles,
);
}
function authcache_authcache_request_exclude() {
if (!($_SERVER['REQUEST_METHOD'] === 'GET' || $_SERVER['REQUEST_METHOD'] === 'HEAD')) {
return t('Only GET and HEAD requests allowed. Method for this request is: @method.', array(
'@method' => $_SERVER['REQUEST_METHOD'],
));
}
if (variable_get('cache') || variable_get('page_cache_without_database')) {
return t('Drupal core page caching for anonymous users active.');
}
$frontscripts = variable_get('authcache_frontcontroller_whitelist', array(
DRUPAL_ROOT . '/index.php',
));
$frontscripts = array_map('realpath', $frontscripts);
if (!in_array(realpath($_SERVER['SCRIPT_FILENAME']), $frontscripts)) {
return t('Not invoked using an allowed front controller.');
}
if (!authcache_backend()) {
return t('No active cache backend.');
}
if (variable_get('authcache_noajax', FALSE) && isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest') {
return t('Ajax request');
}
$alias = drupal_get_path_alias($_GET['q']);
$pagecaching = variable_get('authcache_pagecaching', _authcache_default_pagecaching());
foreach ($pagecaching as $i => $page_rules) {
$rule_num = $i + 1;
if (authcache_role_restrict_access($page_rules['roles'])) {
switch ($page_rules['option']) {
case '0':
case '1':
$page_listed = drupal_match_path($alias, $page_rules['pages']);
if (!!($page_rules['option'] xor $page_listed)) {
return t('Caching disabled by path list of page ruleset #@number', array(
'@number' => $rule_num,
));
}
break;
case '2':
$result = 0;
if (module_exists('php')) {
$result = php_eval($page_rules['pages']);
}
if (empty($result)) {
return t('Caching disabled by PHP rule of page ruleset #@number', array(
'@number' => $rule_num,
));
}
break;
default:
break;
}
if (!empty($page_rules['noadmin']) && path_is_admin(current_path())) {
return t('Not caching admin pages (by page ruleset #@number)', array(
'@number' => $rule_num,
));
}
}
}
}
function authcache_authcache_account_exclude($account) {
if ($account->uid == 1 && !variable_get('authcache_su', 0)) {
return t('Caching disabled for superuser');
}
$extra_roles = authcache_diff_roles($account->roles, authcache_get_roles());
if (!empty($extra_roles)) {
return format_plural(count($extra_roles), 'Account has non-cachable role @roles', 'Account has non-cachable roles @roles', array(
'@roles' => implode(', ', $extra_roles),
));
}
$no_rule_matches = TRUE;
$pagecaching = variable_get('authcache_pagecaching', _authcache_default_pagecaching());
foreach ($pagecaching as $page_rules) {
if (authcache_role_restrict_access($page_rules['roles'], $account)) {
$no_rule_matches = FALSE;
break;
}
}
if ($no_rule_matches) {
return t('Account does not match any page caching rule.');
}
}
function authcache_authcache_preclude() {
if (drupal_set_message()) {
return t('Pending messages');
}
}
function authcache_authcache_cancel() {
$content_type = authcache_get_content_type();
$allowed_mimetypes = preg_split('/(\\r\\n?|\\n)/', variable_get('authcache_mimetype', AUTHCACHE_MIMETYPE_DEFAULT), -1, PREG_SPLIT_NO_EMPTY);
if (!in_array($content_type['mimetype'], $allowed_mimetypes)) {
return t('Only cache allowed HTTP content types (HTML, JS, etc)');
}
if (variable_get('authcache_http200', FALSE) && _authcache_get_http_status() != 200) {
return t('HTTP status 404/403s/etc');
}
if (headers_sent() || ob_get_level() < _authcache_original_ob_level()) {
return t('Private file transfers or headers were unexpectedly sent');
}
foreach (headers_list() as $header) {
if (strpos($header, 'Location:') === 0) {
return t('Location header detected');
}
}
if (function_exists('error_get_last') && ($error = error_get_last())) {
switch ($error['type']) {
case E_NOTICE:
case E_USER_NOTICE:
case E_DEPRECATED:
case E_USER_DEPRECATED:
break;
default:
return t('PHP Error: @error', array(
'@error' => $error['message'],
));
}
}
if (!authcache_backend_check_vary()) {
return t('The Vary header was modified during the request');
}
}
function authcache_authcache_cookie($account) {
$cookies['nocache']['present'] = authcache_precluded();
$cookies['nocache']['value'] = 1;
return $cookies;
}
function authcache_element_info() {
$types['authcache_role_restrict'] = array(
'#input' => TRUE,
'#tree' => TRUE,
'#process' => array(
'authcache_process_role_restrict',
'form_process_container',
),
'#element_validate' => array(
'authcache_validate_role_restrict',
),
'#theme_wrappers' => array(
'container',
),
'#members_only' => FALSE,
);
$types['authcache_duration_select'] = array(
'#input' => TRUE,
'#process' => array(
'authcache_process_duration_select',
),
'#element_validate' => array(
'authcache_validate_duration_select',
),
'#theme_wrappers' => array(
'form_element',
),
);
return $types;
}
function authcache_process_role_restrict($element, &$form_state) {
$authcache_roles = authcache_get_roles();
$allowed_roles = $authcache_roles;
if (!empty($element['#members_only'])) {
unset($allowed_roles[DRUPAL_ANONYMOUS_RID]);
}
$defaults = array(
'custom' => FALSE,
'roles' => $allowed_roles,
);
if (empty($element['#default_value'])) {
$element['#default_value'] = $defaults;
}
else {
$element['#default_value'] = $element['#default_value'] + $defaults;
}
if (empty($allowed_roles)) {
$description = t('Currently there are no roles enabled for authcache. Fix this in <a href="!admin_link">authcache settings</a>.', array(
'!admin_link' => url('admin/config/system/authcache'),
));
}
else {
$description = format_plural(count($allowed_roles), 'The following role is currently enabled for authcache: %roles.', 'The following roles are currently enabled for authcache: %roles.', array(
'%roles' => implode(', ', $allowed_roles),
));
}
$custom_id = drupal_html_id($element['#id'] . '-custom');
$element['custom'] = array(
'#type' => 'checkbox',
'#title' => t('Restrict allowed roles'),
'#default_value' => $element['#default_value']['custom'],
'#description' => $description,
'#disabled' => empty($allowed_roles),
'#id' => $custom_id,
);
$element['roles'] = array(
'#type' => 'checkboxes',
'#title' => t('Allowed roles'),
'#options' => $allowed_roles,
'#default_value' => array_keys($element['#default_value']['custom'] ? authcache_get_role_restrict_roles($element['#default_value']) : $allowed_roles),
'#description' => t('Restrict to the selected roles.'),
'#states' => array(
'visible' => array(
'#' . $custom_id => array(
'checked' => TRUE,
),
),
),
);
return $element;
}
function authcache_validate_role_restrict($element, &$form_state) {
$value = $element['#value'];
if (empty($element['custom']['#value'])) {
$value = NULL;
}
elseif (empty($value['roles'])) {
$value['roles'] = array();
}
else {
$value['roles'] = array_filter($value['roles']);
}
form_set_value($element, $value, $form_state);
}
function authcache_process_duration_select($element, &$form_state) {
$durations = isset($element['#durations']) ? $element['#durations'] : array();
$empty_option = isset($element['#empty_option']) ? $element['#empty_option'] : NULL;
$empty_value = isset($element['#empty_value']) ? $element['#empty_value'] : NULL;
$zero_duration = isset($element['#zero_duration']) ? $element['#zero_duration'] : t('Temporary');
$select_default_value = NULL;
$custom_default_value = NULL;
if (isset($element['#default_value'])) {
$select_default_value = $element['#default_value'];
$custom_default_value = $element['#default_value'];
if (!in_array($select_default_value, $durations)) {
$select_default_value = 'custom';
}
elseif ($custom_default_value == 0) {
$custom_default_value = NULL;
}
}
$options = drupal_map_assoc($durations, function ($duration) use ($zero_duration) {
return (int) $duration > 0 ? format_interval($duration) : $zero_duration;
});
$options['custom'] = t('Custom');
$element['select'] = array(
'#type' => 'select',
'#id' => drupal_html_id($element['#id'] . '-select'),
'#options' => $options,
'#default_value' => $select_default_value,
'#empty_option' => $empty_option,
'#empty_value' => $empty_value,
);
$element['custom'] = array(
'#type' => 'textfield',
'#id' => drupal_html_id($element['#id'] . '-custom'),
'#size' => '25',
'#maxlength' => '30',
'#default_value' => $custom_default_value,
'#element_validate' => array(
'element_validate_integer_positive',
),
'#states' => array(
'visible' => array(
'#' . $element['select']['#id'] => array(
'value' => 'custom',
),
),
),
);
$element['#tree'] = TRUE;
return $element;
}
function authcache_validate_duration_select($element, &$form_state) {
$value = $element['select']['#value'] === 'custom' ? $element['custom']['#value'] : $element['select']['#value'];
form_set_value($element, $value, $form_state);
}
function authcache_get_role_restrict_roles($config) {
$authcache_roles = authcache_get_roles();
if (empty($config['custom'])) {
$result = $authcache_roles;
}
elseif (empty($config['roles'])) {
$result = array();
}
else {
$result = array_intersect_key($authcache_roles, $config['roles']);
}
return $result;
}
function authcache_role_restrict_access($config, $account = NULL) {
global $user;
if (!$account) {
$account = $user;
}
$allowed_roles = authcache_get_role_restrict_roles($config);
$extra_roles = authcache_diff_roles($account->roles, $allowed_roles);
return empty($extra_roles);
}
function authcache_role_restrict_members_access($config, $account = NULL) {
global $user;
if (!$account) {
$account = $user;
}
$allowed_roles = authcache_get_role_restrict_roles($config);
unset($allowed_roles[DRUPAL_ANONYMOUS_RID]);
$extra_roles = authcache_diff_roles($account->roles, $allowed_roles);
return empty($extra_roles);
}