You are here

function better_formats_filter_process_format in Better Formats 8

Same name and namespace in other branches
  1. 7 better_formats.module \better_formats_filter_process_format()

Process callback for form elements that have a text format selector attached.

This callback runs after filter_process_format() and performs additional modifications to the form element.

See also

\Drupal\filter\Element\TextFormat::processFormat()

1 string reference to 'better_formats_filter_process_format'
better_formats_element_info_alter in ./better_formats.module
Implements hook_element_info_alter().

File

./better_formats.module, line 80
Enhances the core input format system by managing input format defaults and settings.

Code

function better_formats_filter_process_format(array &$element, FormStateInterface $form_state, array $complete_form) {

  // Before we make any modifications to the element, record whether or not
  // TextFormat::processFormat() has determined that (for security reasons) the
  // user is not allowed to make any changes to this field. This will happen if
  // the user does not have permission to use the currently-assigned text
  // format.
  $access_denied_for_security = isset($element['format']['format']['#access']) && !$element['format']['format']['#access'];
  if (!empty($element['#better_formats']['settings'])) {
    $betterFormatsSettings = $element['#better_formats']['settings'];
  }
  else {
    return $element;
  }
  if (!empty($element['#better_formats']['entity_type'])) {
    $entity_type = $element['#better_formats']['entity_type'];
  }

  // Whether use the core field module default value to set the default format.
  // See /admin/config/content/formats/settings.
  if (Drupal::config('better_formats.settings')
    ->get('per_field_core')) {
    better_formats_set_default_format($element, $element['#better_formats']['default_value']);
  }

  // Now hide several parts of the element for cosmetic reasons (depending on
  // the permissions of the current user).
  $user = \Drupal::currentUser();
  $user_is_admin = $user
    ->hasPermission('administer filters');

  // The selection should be shown unless proven otherwise.
  $hide_selection = FALSE;

  // If an entity is available then allow Better Formats permission to control
  // visibility.
  if ($entity_type != NULL) {
    $hide_selection = $user
      ->hasPermission('hide format selection for ' . $entity_type);
  }

  // Privileged users should still be able to change the format selection.
  if ($hide_selection && !$user_is_admin) {
    $element['format']['format']['#access'] = FALSE;
  }

  // Allow formats tips to be hidden.
  $hide_tips = $user
    ->hasPermission('hide format tips');
  if ($hide_tips && !$user_is_admin) {
    $element['format']['guidelines']['#access'] = FALSE;
  }

  // Allow format tips link to be hidden.
  $hide_tips_link = $user
    ->hasPermission('hide more format tips link');
  if ($hide_tips_link && !$user_is_admin) {
    $element['format']['help']['#access'] = FALSE;
  }

  // If the element represents a field attached to an entity, we may need to
  // adjust the allowed text format options. However, we don't want to touch
  // this if TextFormat::processFormat() has determined that (for security
  // reasons) the user is not allowed to make any changes; in that case, Drupal
  // core will hide the format selector and force the field to be saved with its
  // current values, and we should not do anything to alter that process.
  if ($entity_type != NULL && !$access_denied_for_security) {

    // Need to only do this on create forms.
    if (!$element['#better_formats']['existing_entity'] && isset($betterFormatsSettings) && !empty($betterFormatsSettings['default_order_toggle']) && !empty($betterFormatsSettings['default_order_wrapper']['formats'])) {
      $order = $betterFormatsSettings['default_order_wrapper']['formats'];
      uasort($order, 'better_formats_text_format_sort');
      $options = [];
      foreach ($order as $id => $weight) {
        if (isset($element['format']['format']['#options'][$id])) {
          $options[$id] = $element['format']['format']['#options'][$id];
        }
      }
      $element['format']['format']['#options'] = $options;
      $options_keys = array_keys($options);
      if (!Drupal::config('better_formats.settings')
        ->get('per_field_core')) {
        better_formats_set_default_format($element, array_shift($options_keys));
      }
    }
    if (isset($betterFormatsSettings) && !empty($betterFormatsSettings['allowed_formats_toggle']) && !empty($betterFormatsSettings['allowed_formats'])) {

      // Filter the list of available formats to those allowed on this field.
      $allowed_fields = array_filter($betterFormatsSettings['allowed_formats']);
      $options =& $element['format']['format']['#options'];
      $options = array_intersect_key($options, $allowed_fields);

      // If there is only one allowed format, deny access to the text format
      // selector for cosmetic reasons, just like filter_process_format() does.
      if (count($options) == 1) {
        $element['format']['format']['#access'] = FALSE;
        $hide_selection = TRUE;
      }

      // If there are no allowed formats, we need to deny access to the entire
      // field, since it doesn't make sense to add or edit content that does
      // not have a text format.
      if (empty($options)) {
        $element['#access'] = FALSE;
      }
      elseif (!isset($options[$element['format']['format']['#default_value']])) {

        // If there is no text in the field, it is safe to automatically assign
        // a new default format. We pick the first available option to be
        // consistent with what filter_default_format() does.
        if (!isset($element['value']['#default_value']) || $element['value']['#default_value'] === '') {
          $formats = array_keys($options);
          better_formats_set_default_format($element, reset($formats));
        }
        else {
          $element['format']['format']['#required'] = TRUE;
          better_formats_set_default_format($element, NULL);

          // Force access to the format selector (it may have been denied
          // previously for cosmetic reasons).
          $element['format']['#access'] = TRUE;
          $element['format']['format']['#access'] = TRUE;
        }
      }
    }
  }

  // If the user is not supposed to see the text format selector, hide all
  // guidelines except those associated with the default format. We need to do
  // this at the end, since the above code may have altered the default format.
  if ($hide_selection && isset($element['format']['format']['#default_value'])) {
    foreach (Element::children($element['format']['guidelines']) as $format) {
      if ($format != $element['format']['format']['#default_value']) {
        $element['format']['guidelines'][$format]['#access'] = FALSE;
      }
    }
  }

  // Keep the format for validation and submit processing but don't sent it to
  // the browser if the user is not supposed to see anything inside of it.
  if ($hide_selection && $hide_tips && $hide_tips_link) {
    unset($element['format']['#type']);
  }
  return $element;
}