You are here

function fasttoggle_get_allowed_links in Fasttoggle 7

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

Parameters

string $type: The typeof of object for which allowed links are being sought.

object $obj: (optional) The object for which allowed links are being sought.

string $object_id: The unique ID (eg nid, uid) of the object being considered.

string $setting_prefix: A prefix that might be added instead of "fasttoggle_" - particularly for items not related to a particular object.

Return value

array Returns an array of links to which the user has access.

16 calls to fasttoggle_get_allowed_links()
fasttoggle_comment_comment_view in module/fasttoggle_comment/fasttoggle_comment.module
Implements hook_comment_view().
fasttoggle_comment_link in module/fasttoggle_comment/fasttoggle_comment.module
Implements hook_link().
fasttoggle_comment_views_handler_field_comment_link::render_link in module/fasttoggle_comment/views/fasttoggle_comment_views_handler_field_comment_link.inc
fasttoggle_do_toggle_option in ./fasttoggle.module
Handle a request to toggle an option.
fasttoggle_field_field_formatter_view in module/fasttoggle_field/fasttoggle_field.module
Implements hook_field_formatter_view().

... See full list

File

./fasttoggle.module, line 419
Enables fast toggling of binary or not so binary settings.

Code

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];
}