fasttoggle.module in Fasttoggle 7
Same filename and directory in other branches
Enables fast toggling of binary or not so binary settings.
File
fasttoggle.moduleView source
<?php
/**
* @file
* Enables fast toggling of binary or not so binary settings.
*/
define('FASTTOGGLE_ACCESS_DENIED', -1);
define('FASTTOGGLE_ACCESS_UNDECIDED', 0);
define('FASTTOGGLE_ACCESS_ALLOWED', 1);
/**
* Implements hook_menu().
*
* This function creates the menu links for all fasttoggle items, so modules
* implementing fasttoggle support don't need to do anything in this area.
*/
function fasttoggle_menu() {
$items = array();
$items['admin/config/system/fasttoggle'] = array(
'title' => 'Fasttoggle',
'description' => 'Configure what fast toggling options are available.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'fasttoggle_settings_form',
),
'file' => 'fasttoggle.admin.inc',
'access arguments' => array(
'administer fasttoggle',
),
);
$configs = fasttoggle_get_available_links();
// For each available link, create a menu item.
// The config for an item can override the object type we're expecting, but
// the general pattern is /fasttoggle/{obj_type}/{obj_id}/{group}/{instance}.
if (!empty($configs)) {
foreach ($configs as $key => $data) {
$object_type = $key;
$path_item = "%{$key}";
if (isset($data['override_object_type'])) {
if ($data['override_object_type'] > '') {
$path_item = "%{$data['override_object_type']}";
}
else {
$path_item = "%";
}
}
else {
if (isset($data['object_type'])) {
$path_item = "%{$data['object_type']}";
}
}
$path = "fasttoggle/{$object_type}/{$path_item}/%/%";
$items[$path] = array(
'title' => 'Toggle',
'page callback' => 'fasttoggle_do_toggle_option',
'page arguments' => [
1,
2,
3,
4,
],
'access callback' => TRUE,
// Access checking is handled in hook_fasttoggle_allowed_links().
'type' => MENU_CALLBACK,
'theme callback' => 'ajax_base_page_theme',
);
}
}
return $items;
}
/**
* Implements hook_perm().
*
* Individual modules are responsible for implementing any additional
* permissions, but they should generally use the same permissions
* that are normally used to access the field, plus any system wide
* and content-type specific options for en/disabling the links.
*/
function fasttoggle_permission() {
return array(
'administer fasttoggle' => array(
'title' => t('Administer Fasttoggle'),
),
);
}
/**
* Implements hook_help().
*/
function fasttoggle_help($path, $arg) {
if ($path == 'admin/config/system/fasttoggle') {
return t('Configure what fast toggling options are available.');
}
}
/**
* Get a value from an object.
*
* Get the value of an object's attribute. There are three options:
* - A group specific function
* - An attribute of the object with the name overridden at instance level
* - $object->$instance without modification.
*
* @param array $options
* An array containing the configuration data for the object type.
* @param string $group
* A string, containing the group to which the attribute belongs.
* @param string $instance
* The name of the attribute being accessed (string).
* @param object $object
* An instance of the object containing the value to be returned.
*
* @return mixed
* The value of the attribute.
*/
function fasttoggle_get_object_value(array $options, $group, $instance, $object) {
if (isset($options['fields'][$group]['value_fn'])) {
return $options['fields'][$group]['value_fn']($options, $group, $instance, $object);
}
else {
if (isset($options['fields'][$group]['instances'][$instance]['value_key'])) {
return $object->{$options['fields'][$group]['instances'][$instance]['value_key']};
}
else {
return $object->{$instance};
}
}
}
/**
* Add fasttoggle abilities to a link.
*
* @param array $option_info
* The configuration that controls this link's content and appearance.
* @param string $group
* The group of configuration options to which the link to be rendered
* belongs.
* @param string $instance
* The instance name of the link to be rendered.
* @param object $object
* An instance of the object to be modified by the link, used to get the
* current value for the link.
* @param int $format
* The type of rendering of the link to provide to the caller.
* @param string $view
* (optional; defaults to NULL) An extra parameter to be passed to an ajax
* renderers, telling them how to render a modified object.
*
* @return mixed
* A complete HTML link, a form API array or a link array structure for use
* in hook_link.
*/
function fasttoggle(array $option_info, $group, $instance, $object, $format, $view = NULL) {
static $sent = FALSE;
static $label_style = -1;
if ($label_style == -1) {
$label_style = variable_get('fasttoggle_label_style', FASTTOGGLE_LABEL_STATUS);
}
$current_value = fasttoggle_get_object_value($option_info, $group, $instance, $object);
$title = $option_info['fields'][$group]['instances'][$instance]['labels'][$label_style][$current_value];
if (empty($option_info['fields']['callback_fn'])) {
$view = is_null($view) ? '' : "/{$view}";
$callback = "fasttoggle/{$option_info['object_type']}/{$object->{$option_info['id_field']}}/{$group}/{$instance}{$view}";
}
else {
$callback = $option_info['fields']['callback_fn']($option_info, $group, $instance, $object, $view);
}
// Allow any rewriting of the URL to be done now, so our POST doesn't get
// turned into a GET.
if (module_exists('spaces')) {
$space = spaces_get_space_from_object($option_info['object_type'], $object);
$options = array();
if ($space && module_exists('purl')) {
$original_path = $callback;
$purl_params = array(
'query' => drupal_get_query_parameters($_GET, [
'q',
]),
'purl' => [
'provider' => "spaces_{$space->type}",
'id' => $object->{$option_info['id_field']},
'absolute' => TRUE,
],
);
$callback = url($callback, $purl_params);
// Strip the leading slash.
$callback = substr($callback, 1);
}
}
$token = $group . '_' . $instance . '_' . $object->{$option_info['id_field']};
$selector_class = 'fasttoggle-status-' . $option_info['object_type'] . '-' . $object->{$option_info['id_field']} . '-' . $group . '-' . $instance;
$status_class = 'fasttoggle-status-' . $option_info['object_type'] . '-' . $group . '-' . $instance . '-' . $current_value;
// Only include the support files once.
if (!$sent) {
$sent = TRUE;
drupal_add_library('system', 'drupal.ajax');
drupal_add_library('system', 'jquery.form');
}
$attributes = array(
'class' => array(
'fasttoggle',
'use-ajax',
$selector_class,
$status_class,
),
'title' => t('Toggle this setting'),
);
$query = drupal_get_destination() + array(
'token' => drupal_get_token($token),
);
switch ($format) {
case FASTTOGGLE_FORMAT_HTML:
return l($title, $callback, array(
'attributes' => $attributes,
'query' => $query,
));
case FASTTOGGLE_FORMAT_LINK_ARRAY:
return array(
'title' => $title,
'href' => $callback,
'query' => $query,
'attributes' => $attributes,
);
case FASTTOGGLE_FORMAT_FORM:
return array(
'#type' => 'link',
'#title' => $title,
'#href' => $callback,
'#options' => array(
'query' => $query,
'attributes' => $attributes,
),
);
}
}
/**
* Return a link.
*
* @param string $type
* The type of object for which a link is wanted.
* @param object $obj
* The instance of the object (eg user ID)
* @param int $teaser
* Whether the link is to a teaser.
*
* @return array
* The link render array.
*/
function fasttoggle_link($type, $obj, $teaser = FALSE) {
$links = array();
$options = fasttoggle_get_allowed_links($type, $obj);
if (!empty($options)) {
switch ($type) {
case 'node':
foreach (array_keys($options['fields']['status']['instances']) as $key) {
$links['fasttoggle_' . $key] = fasttoggle($options, 'status', $key, $obj, FASTTOGGLE_FORMAT_LINK_ARRAY);
}
break;
case 'comment':
fasttoggle_load_comment($obj);
foreach (array_keys($options['fields']['status']['instances']) as $key) {
$links['fasttoggle_' . $key] = fasttoggle($options, 'status', $key, $obj, FASTTOGGLE_FORMAT_LINK_ARRAY);
}
break;
// User is not one of the standard types for hook_link(). This
// use enables adding of user links to a user profile.
case 'user':
if (!empty($options['fields']['status']['instances'])) {
foreach (array_keys($options['fields']['status']['instances']) as $key) {
$links['fasttoggle_' . $key] = fasttoggle($options, 'status', $key, $obj, FASTTOGGLE_FORMAT_LINK_ARRAY);
}
}
break;
}
}
return $links;
}
/**
* Get all potential links for an object type.
*
* @param string $type
* (optional) The object type for which available links are being sought.
* @param object $obj
* (optional) An object instance for which available links are being sought.
* The object's subtype (where applicable) may be used to further filter
* the links which are returned.
*
* @return mixed
* If the parameter is NULL, an array containing all available links, indexed
* by type, is returned. If $type if not NULL, only the subtree for that type
* is returned. In the later case, hooks not supporting the chosen type may
* skip the work of doing any calculations or calls, saving time andmemory.
*/
function fasttoggle_get_available_links($type = NULL, $obj = NULL) {
static $config = array();
if (empty($config) || !is_null($type) && empty($config[$type])) {
// The cache is completely empty or the type hasn't been cached.
if (is_null($type)) {
// Get all available links.
$config = module_invoke_all('fasttoggle_available_links');
}
else {
// Just interested in one type.
$temp = module_invoke_all('fasttoggle_available_links', $type, $obj);
if (!isset($temp[$type])) {
$temp[$type] = array();
}
if (is_null($obj)) {
$config[$type] = $temp[$type];
}
else {
// Interested in a particular object. Don't cache.
return $temp[$type];
}
}
}
return is_null($type) ? $config : $config[$type];
}
/**
* Carry out a series of access checks.
*
* @param array $checks
* The list of checks to perform.
* @param object $obj
* The object being considered.
* @param string $type
* The type of object.
* @param string $group
* The setting group.
* @param string $instance
* The instance of the setting.
*
* @return int
* The tristate result (ALLOWED / DENIED / UNDECIDED).
*/
function fasttoggle_check_access(array $checks = array(), $obj = NULL, $type = NULL, $group = NULL, $instance = NULL) {
foreach ($checks as $order => $check) {
if (!function_exists($check)) {
// Err on the side of caution, and say why.
drupal_set_message("Fasttoggle access check function '{$check}' was not found. Denying access to the setting(s) affected.", 'error');
return FASTTOGGLE_ACCESS_DENIED;
}
$result = $check($obj, $type, $group, $instance);
if ($result != FASTTOGGLE_ACCESS_UNDECIDED) {
return $result;
}
}
return FASTTOGGLE_ACCESS_UNDECIDED;
}
/**
* Get the tristate value (DENIED / UNDECIDED) matching a test outcome.
*
* @param bool $condition_outcome
* The boolean outcome of a test.
*
* @return int
* The tristate value to be used.
*/
function fasttoggle_deny_access_if($condition_outcome) {
return $condition_outcome ? FASTTOGGLE_ACCESS_DENIED : FASTTOGGLE_ACCESS_UNDECIDED;
}
/**
* Get the tristate value (ALLOWED / UNDECIDED) matching a test outcome.
*
* @param bool $condition_outcome
* The boolean outcome of a test.
*
* @return int
* The tristate value to be used.
*/
function fasttoggle_allow_access_if($condition_outcome) {
return $condition_outcome ? FASTTOGGLE_ACCESS_ALLOWED : FASTTOGGLE_ACCESS_UNDECIDED;
}
/**
* Get the list of links the current user may utilise.
*
* I would like to use the object subtype and ID from the object using
* the config, but that's a chicken and the egg problem - we can't tell
* get_available_links how to filter the config it returns until we have the
* config it returns available to look up the field names. And we can't
* rely on the caller having the requisite knowledge either.
*
* Access is applied at each level to a parent and all of its children.
* In other words, the objectwide settings control all access, group level
* settings control all settings within a group, and individual setting
* access functions control access to just that setting.
*
* Access is also PAM-like. 'Undecided' means we haven't made a decision one
* way or the other. If we get through the whole chain and are still on
* 'Undecided', permission is denied. Any access checker along the list
* may say 'Denied' or 'Allowed', thereby determining the final outcome.
*
* So the final access is determined by:
* - admin/config/system/fasttoggle settings ("sitewide_current_values")
* - object type config such as node type settings ("current_values")
* - access hooks at the objecttype, setting group and individual toggle
* level
*
* @param string $type
* The typeof of object for which allowed links are being sought.
* @param object $obj
* (optional) The object for which allowed links are being sought.
* @param string $object_id
* The unique ID (eg nid, uid) of the object being considered.
* @param string $setting_prefix
* A prefix that might be added instead of "fasttoggle_" - particularly for
* items not related to a particular object.
*
* @return array
* Returns an array of links to which the user has access.
*/
function fasttoggle_get_allowed_links($type, $obj = NULL, $object_id = 0, $setting_prefix = NULL) {
static $options_cache = array();
$setting_key = NULL;
$objectwide_access = FASTTOGGLE_ACCESS_UNDECIDED;
// Use caching if possible.
if (empty($options_cache[$type][$object_id])) {
// Start by getting all available links for the object type.
$filtering = fasttoggle_get_available_links($type, $obj);
/* Now begin to do access checks. */
// Get defaults for objectwide and lower level config.
$defaults = fasttoggle_defaults_from_config_data($filtering);
// If there's a toplevel access check function and it fails, nothing is
// permitted.
if (isset($filtering['access'])) {
$objectwide_access = fasttoggle_check_access($filtering['access'], $obj, $type);
}
// If access is denied at a objectwide level, we can just clear the array
// and drop out. If it is allowed at a objectwide level, we still want to
// remove the options that have been turned off in the objectwide and node
// type forms.
if ($objectwide_access === FASTTOGGLE_ACCESS_DENIED) {
$filtering = array();
}
else {
foreach ($filtering['fields'] as $group_name => $group_data) {
$groupwide_access = FASTTOGGLE_ACCESS_UNDECIDED;
if (!isset($sitewide_setting_key) || isset($group_data['#title'])) {
// Site wide settings.
$sitewide_setting_key = "fasttoggle_{$type}_{$group_name}_settings";
$sitewide_current_values = array_filter(variable_get($sitewide_setting_key, $defaults));
}
// Get the setting variable, if necessary.
if (!isset($setting_key) || isset($group_data['#title'])) {
// More localised settings.
$sub_type = isset($obj) && isset($filtering['subtype_field']) ? $obj->{$filtering['subtype_field']} : "";
// For nodes, the setter adds the node type so we need to do so too
// when getting only.
if (isset($setting_prefix)) {
$objfield = $filtering['subtype_field'];
$setting_key = "{$setting_prefix}_{$type}_{$obj->{$objfield}}";
}
else {
$setting_key = "fasttoggle_{$type}_{$group_name}_settings";
}
$current_values = array_filter(variable_get($setting_key, $defaults));
// Some forms (node_type_admin...) do array_keys on the values saved.
$temp = array_reverse(array_keys($current_values), TRUE);
if (array_pop($temp) === 0) {
$current_values = array_flip($current_values);
}
if (isset($filtering['write_key'])) {
$setting_key = $filtering['write_key'];
}
}
// Access at the group level? Sitewide access being allowed has
// priority.
if ($objectwide_access === FASTTOGGLE_ACCESS_UNDECIDED && isset($group_data['access'])) {
$groupwide_access = fasttoggle_check_access($group_data['access'], $obj, $type, $group_name);
if ($groupwide_access === FASTTOGGLE_ACCESS_DENIED) {
unset($filtering['fields'][$group_name]);
continue;
}
}
// If we reach here, objectwide and groupwide access checks have
// returned either allowed or undecided. At this point, we need to check
// whether the settings forms have disabled the individual toggles.
foreach ($group_data['instances'] as $instance_name => $instance_data) {
$group_contents =& $filtering['fields'][$group_name]['instances'];
// Access at the instance level?
$value_key = "{$group_name}_{$instance_name}";
// Enabled in sitewide form?
if (!isset($sitewide_current_values[$value_key])) {
unset($group_contents[$instance_name]);
continue;
}
// Enabled in group form? (Eg node type)
if (!isset($current_values[$value_key])) {
unset($group_contents[$instance_name]);
continue;
}
// The final check - toggle level access? If objectwide or groupwide
// access is allowed, no check is needed.
if ($objectwide_access === FASTTOGGLE_ACCESS_UNDECIDED && $groupwide_access === FASTTOGGLE_ACCESS_UNDECIDED) {
$result = FASTTOGGLE_ACCESS_UNDECIDED;
if (isset($instance_data['access'])) {
$result = fasttoggle_check_access($instance_data['access'], $obj, $type, $group_name, $instance_name);
}
// If access is not explicitly permitted, it is denied.
if ($result !== FASTTOGGLE_ACCESS_ALLOWED) {
unset($group_contents[$instance_name]);
}
}
}
if (empty($group_contents)) {
unset($filtering['fields'][$group_name]);
}
}
if (empty($filtering['fields'])) {
$filtering = array();
}
}
$options_cache[$type][$object_id] = $filtering;
}
return $options_cache[$type][$object_id];
}
/**
* Handle a request to toggle an option.
*
* Menu callback. Toggle options for an object if the action is confirmed via
* POST. Otherwise, display a confirmation form.
*
* @param string $object_type
* The type of object being handled.
* @param object $object
* An instance of the object to be modified.
* @param string $group
* The group to which the setting being modified belongs.
* @param string $option
* The option being toggled.
* @param string $view
* (Optional) The view of the object to be rendered.
*
* @return mixed
* If the access check fails, returns MENU_NOT_FOUND (=> 404). If submission
* is non-ajax and not confirmed, a confirmation form is displayed. If the
* link is ajax or the confirmation is provided via the form, the value is
* toggled to the next in the sequence and the function either returns the
* ajax for updating the link (and potentially replacing the body of the
* rendered object with updated content) or executes drupal_goto() in the
* case of the form submission.
*/
function fasttoggle_do_toggle_option($object_type, $object, $group, $option, $view = NULL) {
global $user;
$options = fasttoggle_get_allowed_links($object_type, $object);
$label_style = variable_get('fasttoggle_label_style', FASTTOGGLE_LABEL_STATUS);
$id_field = $options['id_field'];
$group_data = $options['fields'][$group];
// Check if the action is valid. This is essential to ensure the user has
// access to the action.
if (!isset($group_data['instances'][$option]) || !isset($_GET['token']) || !drupal_valid_token($_GET['token'], $group . '_' . $option . '_' . $object->{$id_field}, TRUE)) {
if (isset($_POST['js']) && $_POST['js']) {
$ajax_commands = array(
ajax_command_alert(t('Invalid ajax request')),
);
echo ajax_render($ajax_commands);
exit;
}
else {
return MENU_NOT_FOUND;
}
}
// The action is confirmed: either via form submit or via AJAX/POST.
if (isset($_POST['confirm']) && $_POST['confirm'] || isset($_POST['js']) && $_POST['js']) {
$selectorClass = 'fasttoggle-status-' . $object_type . '-' . $object->{$id_field} . '-' . $group . '-' . $option;
$label_data = $group_data['instances'][$option];
if (isset($group_data['new_value_fn'])) {
$value = $group_data['new_value_fn']($object, $label_data['value_key']);
}
else {
$current_value = fasttoggle_get_object_value($options, $group, $option, $object);
$labels = $label_data['labels'][$label_style];
// Find the current value. We need to cast as strings to ensure
// we stop at the right value.
while ((string) key($labels) !== (string) $current_value) {
next($labels);
}
do {
// Get the next value and wrap back to the start if necessary.
if (next($labels) === FALSE) {
reset($labels);
}
// Don't stop on the 'unset' value if the field is required.
if (key($labels) === '[unset]' && !$label_data['optional']) {
if (next($labels) === FALSE) {
reset($labels);
}
}
// Go again if this value isn't allowed.
} while (isset($label_data['allowed_values']) && !in_array((string) key($labels), $label_data['allowed_values']));
// And get the new value we'll actually use.
$value = key($labels);
}
// Save the new value.
if (!empty($group_data['save_fn'])) {
$group_data['save_fn']($options, $group, $option, $value, $object);
}
else {
$options['save_fn']($options, $group, $option, $value, $object);
}
$label = $labels[$value];
$object_label = entity_label($object_type, $object);
$newClass = 'fasttoggle-status-' . $object_type . '-' . $group . '-' . $option . '-' . $value;
watchdog('fasttoggle', '@type %title @option toggled to @value.', [
'@type' => drupal_ucfirst($object_type),
'%title' => $object_label,
'@option' => $option == $group ? $option : $group . ' ' . $option,
'@value' => $label,
]);
// Let other modules respond.
module_invoke_all('fasttoggle_toggle', $object_type, $object, $group, $option);
// Output the new status for the updated link text on AJAX changes.
if (isset($_POST['js']) && $_POST['js']) {
drupal_add_http_header('Content-Type', 'text/javascript; charset=utf-8');
// l() (invoked by fasttoggle()) adds the active class to our new link.
// But the original link doesn't get it added, so clicking the link
// results in an extra class being applied. Strip the active class here
// (assuming it's added to the end of the classes, so we get apples for
// apples.
$new_link = fasttoggle($options, $group, $option, $object, FASTTOGGLE_FORMAT_HTML, $view);
$new_link = preg_replace('/class="(.*) active"/', 'class="$1"', $new_link);
$ajax_commands = array(
ajax_command_replace('.' . $selectorClass, $new_link),
ajax_command_invoke('body', 'trigger', [
'FasttoggleTrigger',
$newClass,
]),
);
$params = array(
'group' => $group,
'option' => $option,
'view' => $view,
);
drupal_alter('fasttoggle_ajax', $ajax_commands, $object_type, $object, $params);
echo ajax_render($ajax_commands);
exit;
}
else {
drupal_goto();
}
}
else {
// The action is not confirmed. The user came here through a regular link;
// no AJAX was involved. That means, we need a confirmation form so that
// we get a POST form.
return drupal_get_form('fasttoggle_do_option_confirm', $object_type, $object->{$options['title_field']}, $options['fields'][$group]['instances'][$option]['labels'][$label_style][intval(!$object->{$option})]);
}
}
/**
* Confirmation form for the option change of a object.
*
* @param array $form
* The form render array.
* @param array $form_state
* The form state array.
* @param string $object_type
* The type of object being used.
* @param string $title
* The title for the attribute.
* @param string $option
* The potential new value for the object attribute.
*
* @return array
* The render array for the confirmation dialog.
*/
function fasttoggle_do_option_confirm(array $form, array $form_state, $object_type, $title, $option) {
return confirm_form([], t('Are you sure you want to set the %obj_type %title to %option?', [
'%obj_type' => $object_type,
'%title' => $title,
'%option' => $option,
]), $_GET['destination'] ? $_GET['destination'] : $object_type . '/' . $object->{$id_field}, '', t('Change'), t('Cancel'));
}
/**
* Get default values from configuration data.
*
* @param array $config_data
* The configuration data to be checked.
*
* @return array
* The default values, keyed by group and instance concatenated with an
* underscore.
*/
function fasttoggle_defaults_from_config_data(array $config_data) {
$result = array();
foreach ($config_data['fields'] as $group_name => $group_data) {
foreach ($group_data['instances'] as $instance_name => $instance_data) {
if (isset($instance_data['default']) && $instance_data['default'] !== FALSE) {
$result["{$group_name}_{$instance_name}"] = $instance_data['default'];
}
}
}
return $result;
}
/**
* Implements hook_block_info().
*
* Register a block for displaying fasttoggle links.
*/
function fasttoggle_block_info() {
$blocks['block'] = array(
'info' => t('Fasttoggle Links'),
'weight' => -99,
'status' => 1,
'region' => 'content',
'cache' => DRUPAL_NO_CACHE,
);
return $blocks;
}
/**
* Return the list of links after adding a new entry if provided.
*
* @param mixed $link
* The link.
* @param string $group
* The group to which the link belongs.
* @param string $key
* The key within the group.
* @param string $instance
* The instance of the key.
*
* @return array
* The list of links so far, grouped by group and key.
*/
function fasttoggle_block_link_register($link = NULL, $group = NULL, $key = NULL, $instance = NULL) {
static $links = array();
if (!is_null($link)) {
// Avoid duplicates by keying by the content.
if (is_null($group)) {
$group = '';
}
if (is_null($key)) {
$key = '';
}
if (is_null($instance)) {
$instance = '';
}
if (!isset($links[$group])) {
$links[$group] = array();
}
if (!isset($links[$key])) {
$links[$key] = array();
}
$links[$group][$key][$instance] = $link;
}
return $links;
}
/**
* Implements hook_block_view().
*/
function fasttoggle_block_view($delta = '') {
$items = fasttoggle_block_link_register();
if (empty($items)) {
return;
}
foreach ($items as $group => $group_content) {
foreach ($group_content as $key => $key_content) {
$group_content[$key] = implode("<br />", $key_content);
}
$items[$group] = "<div class='fasttoggle-block-key'>" . implode("</div><div class='fasttoggle-block-key'>", $group_content) . "</div>";
}
$items = "<div class='fasttoggle-block-group'>" . implode("</div><div class='fasttoggle-block-group'>", $items) . "</div>";
$block = array(
'subject' => t('Fasttoggle Links'),
'content' => [
'#markup' => theme('container', [
'element' => [
'#children' => $items,
'#attributes' => [
'class' => 'fasttoggle-block',
],
],
]),
'#attached' => [
'css' => [
drupal_get_path('module', 'fasttoggle') . '/css/fasttoggle.css',
],
],
],
);
return $block;
}
Functions
Name![]() |
Description |
---|---|
fasttoggle | Add fasttoggle abilities to a link. |
fasttoggle_allow_access_if | Get the tristate value (ALLOWED / UNDECIDED) matching a test outcome. |
fasttoggle_block_info | Implements hook_block_info(). |
fasttoggle_block_link_register | Return the list of links after adding a new entry if provided. |
fasttoggle_block_view | Implements hook_block_view(). |
fasttoggle_check_access | Carry out a series of access checks. |
fasttoggle_defaults_from_config_data | Get default values from configuration data. |
fasttoggle_deny_access_if | Get the tristate value (DENIED / UNDECIDED) matching a test outcome. |
fasttoggle_do_option_confirm | Confirmation form for the option change of a object. |
fasttoggle_do_toggle_option | Handle a request to toggle an option. |
fasttoggle_get_allowed_links | Get the list of links the current user may utilise. |
fasttoggle_get_available_links | Get all potential links for an object type. |
fasttoggle_get_object_value | Get a value from an object. |
fasttoggle_help | Implements hook_help(). |
fasttoggle_link | Return a link. |
fasttoggle_menu | Implements hook_menu(). |
fasttoggle_permission | Implements hook_perm(). |
Constants
Name![]() |
Description |
---|---|
FASTTOGGLE_ACCESS_ALLOWED | |
FASTTOGGLE_ACCESS_DENIED | @file Enables fast toggling of binary or not so binary settings. |
FASTTOGGLE_ACCESS_UNDECIDED |