You are here

function og_field_widget_form in Organic groups 7

Same name and namespace in other branches
  1. 7.2 includes/og.field.inc \og_field_widget_form()

Implements hook_field_widget_form().

Unlike options_field_widget_form() our widget's logic is a bit different, as the form element type is a result of the user's access to the groups. For example a privileged user may see all groups as an optgroup select list, where the groups are divided to "My groups" and "Other groups". This means that the $element['#type'] is a result of the options passed to $element['#options'].

File

./og.field.inc, line 176
Field module functionality for the Organic groups module.

Code

function og_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $base) {
  $element = $base;
  $widget = $instance['widget'];
  switch ($widget['type']) {
    case OG_AUDIENCE_AUTOCOMPLETE_WIDGET:
      $element += array(
        '#type' => 'textfield',
        '#default_value' => isset($items[$delta]['gid']) ? $items[$delta]['gid'] : NULL,
        '#autocomplete_path' => $instance['widget']['settings']['autocomplete_path'] . '/' . $field['field_name'],
        '#size' => $instance['widget']['settings']['size'],
        '#element_validate' => array(
          'og_field_audience_autocomplete_validate',
        ),
        '#value_callback' => 'og_field_audience_autocomplete_value',
      );
      $return = array(
        'gid' => $element,
      );
      break;
    case OG_AUDIENCE_WIDGET:

      // Determine if a user may see other groups as-well.
      $opt_group = FALSE;
      if ($instance['widget']['settings']['opt_group'] == 'always' || $instance['widget']['settings']['opt_group'] == 'auto' && user_access('administer group')) {
        $opt_group = TRUE;
      }

      // If this is a user account, base the list on the account being edited.
      $account = NULL;
      if (isset($form['#user'])) {
        $account = $form['#user'];
      }

      // Get all the groups divided to "content groups" and "other groups".
      $audience = og_field_audience_options($opt_group, $account);

      // Get all groups that should be excluded.
      $excludes = array();

      // If it's an existing group, then exclude itself, as in some cases a group
      // can act also as a group content, but we want to prevent associating the
      // group to itself.
      if (!empty($form['#' . $element['#entity_type']])) {
        list($id) = entity_extract_ids($element['#entity_type'], $form['#' . $element['#entity_type']]);
        if ($group = og_get_group($element['#entity_type'], $id)) {
          $excludes[$group->gid] = $group->gid;
        }
      }

      // Get default values from URL, or from the edited entity.
      $default_values = og_get_context_by_url();

      // Keep the group ID of the selected items, as they might be needed again,
      // and we don't want to iterate over the items again.
      $items_gid = array();
      if (!empty($items)) {
        $gids = array();
        foreach ($items as $item) {
          $gids[] = $item['gid'];
        }

        // In case there are deleted groups, we trim the list to only the
        // existing ones.
        $gids = array_keys(og_load_multiple($gids));
        foreach ($gids as $gid) {
          $default_values[] = $gid;
          $items_gid[] = $gid;
        }
      }

      // Since array_unique compares values according to (string)$a==(string)$b, this also cleans up duplicates such as "1" and 1
      $default_values = array_unique($default_values);
      foreach (array(
        'content groups',
        'other groups',
      ) as $key) {
        if (!empty($audience[$key])) {

          // Get the label un-sanitized, as they will be laster sanitized
          // according to the form type.
          $audience[$key] = og_label_multiple($audience[$key], FALSE);
        }
      }

      // The group options presented to the user.
      $options = array();
      $hidden_selected_gids = array();
      $type = 'select';
      if ($opt_group) {

        // Show "My groups" and "Other groups".
        if ($my_groups = array_diff_key($audience['content groups'], $excludes)) {
          $options += array(
            t('My groups') => $my_groups,
          );
        }
        if ($other_groups = array_diff_key($audience['other groups'], $excludes)) {
          $options += array(
            t('Other groups') => $other_groups,
          );
        }
      }
      else {

        // Show only "My groups".
        $options = array_diff_key($audience['content groups'], $excludes);

        // If there are items that are already selected but the user doesn't
        // have access to them, we need to keep track of them.
        $hidden_selected_gids = drupal_map_assoc(array_diff($items_gid, array_keys($options)));
      }
      if (empty($options)) {

        // There are no group, so don't show any input element.
        $type = 'item';
        $element['#description'] = t('There are no groups you can select from.');
        $properties = array();
      }
      else {
        if (empty($element['#description'])) {
          $element['#description'] = t('Select the groups this content should be associated with.');
        }
        $element['#multiple'] = $field['cardinality'] > 1 || $field['cardinality'] == FIELD_CARDINALITY_UNLIMITED;

        // Don't make the field required, if there are no groups.
        $element['#required'] = $element['#required'] && !empty($options);
        $properties = _options_properties($type, $element['#multiple'], $element['#required'], $options);

        // If the element isn't required and cardinality is more than 1, and there
        // are some options, and a "none" option.
        if (!$element['#required'] && !$element['#multiple']) {

          // Use a dummy instance in order to use theme('options_none');
          $dummy_instance['widget']['type'] = 'options_select';
          $options = array(
            '_none' => theme('options_none', array(
              'instance' => $dummy_instance,
            )),
          ) + $options;
        }
      }
      $element += array(
        // Input should be TRUE only if there are groups that can be selected.
        '#input' => $type != 'item',
        '#type' => $type,
        '#options' => $options,
        '#default_value' => $default_values,
        '#attributes' => array(
          'class' => array(
            'group-audience',
          ),
        ),
        '#disabled' => empty($options),
        // Re-use options widget element validation, to correctly transform
        // submitted values from field => delta to delta => field.
        // @see options_field_widget().
        '#value_key' => 'gid',
        '#element_validate' => $type != 'item' ? array(
          'options_field_widget_validate',
        ) : array(),
        '#properties' => $properties,
        // Add OG specific context.
        '#opt_group' => $opt_group,
        '#audience' => $audience,
        '#hidden_selected_gids' => $hidden_selected_gids,
      );
      $return = $element;
      break;
  }
  return $return;
}