X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs-website;a=blobdiff_plain;f=web%2Fmodules%2Fcontrib%2Fbetter_formats%2Fbetter_formats.module;fp=web%2Fmodules%2Fcontrib%2Fbetter_formats%2Fbetter_formats.module;h=5680144c4ff5c70a1c019df1aa30f1368e79e271;hp=0000000000000000000000000000000000000000;hb=8acec36f19c470dfcda1ae2336826a782f41874c;hpb=e0411c4e83ba0d079034db83c3f7f55be24a0e35 diff --git a/web/modules/contrib/better_formats/better_formats.module b/web/modules/contrib/better_formats/better_formats.module new file mode 100644 index 000000000..5680144c4 --- /dev/null +++ b/web/modules/contrib/better_formats/better_formats.module @@ -0,0 +1,429 @@ +getFormObject(); + + if ($form_object instanceof Drupal\Core\Entity\ContentEntityForm) { + $entity = $form_state->getFormObject()->getEntity(); + $entity_type = $entity->getEntityTypeId(); + $field_name = reset($element['#parents']); + $field_definition = $entity->getFieldDefinition($field_name); + + if ($field_definition instanceof ThirdPartySettingsInterface) { + $bf = $field_definition->getThirdPartySettings('better_formats'); + + if (Drupal::config('better_formats.settings')->get('per_field_core')) { + $field_defaults = $field_definition->getDefaultValue($entity); + $default_value = array_shift($field_defaults); + better_formats_set_default_format($element, $default_value['format']); + } + } + } + elseif ($form_object instanceof Drupal\field_ui\Form\FieldConfigEditForm) { + $entity = $form_state->getFormObject()->getEntity(); + $entity_type = $entity->getTargetEntityTypeId(); + $bf = $entity->getThirdPartySettings('better_formats'); + } + else { + return $element; + } + + // 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) { + $eid = $entity->id(); + + // Need to only do this on create forms. + if (empty($eid) && isset($bf) && !empty($bf['default_order_toggle']) && !empty($bf['default_order_wrapper']['formats'])) { + $order = $bf['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($bf) && !empty($bf['allowed_formats_toggle']) && !empty($bf['allowed_formats'])) { + // Filter the list of available formats to those allowed on this field. + $allowed_fields = array_filter($bf['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; + } + // Otherwise, if the current default format is no longer one of the + // allowed options, a new default format must be assigned. + 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)); + } + // Otherwise, it is unsafe to automatically assign a new default format + // (since this will display the content in a way that was not + // originally intended and might be dangerous, e.g. if the content + // contains an attempted XSS attack). A human must explicitly decide + // which new format to assign, so we force the field to be required but + // with no default value, similar to what filter_process_format() does. + // Although filter_process_format() limits this functionality to users + // with the 'administer filters' permission, we can allow it for any + // user here since we know that the user already has permission to use + // the current format; thus, there is no danger of exposing unformatted + // text (for example, raw PHP code) that they are otherwise not allowed + // to see. + 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; +} + +/** + * Determine if text field type uses text formatter. + * + * @param string $type + * The field type to check. + * + * @return bool + * TRUE if input field type uses text formatter, FALSE if it does not. + */ +function better_formats_is_text_format($type) { + if (in_array($type, ['text', 'text_long', 'text_with_summary'], TRUE)) { + return TRUE; + } + else { + return FALSE; + } +} + +/** + * Set the default format for the element. + * + * @param array $element + * The form element to set the default format on. + * @param string $default_value + * The id for the format to set as default. + */ +function better_formats_set_default_format(array &$element, $default_value) { + $element['#format'] = $default_value; + $element['format']['format']['#default_value'] = $default_value; +} + +/** + * Sort text formats by weight. + * + * @param array $a + * Array containing weight value to compare. + * @param array $b + * Array containing weight value to compare. + * + * @return bool + * TRUE if the weight of $a is greater than $b, FALSE if weight of $b is + * greater than $a or equal to $a. + */ +function better_formats_text_format_sort($a, $b) { + return $a['weight'] > $b['weight']; +} + +/** + * Implements hook_form_FORM_ID_alter(). + */ +function better_formats_form_field_config_edit_form_alter(&$form, FormStateInterface $form_state, $form_id) { + $entity = $form_state->getFormObject()->getEntity(); + + // Only alter fields with text processing and if admin has chosen. + $text_processing = better_formats_is_text_format($entity->getType()); + $config = Drupal::config('better_formats.settings'); + + if ($text_processing && $config->get('per_field_core')) { + // Add a submit handler to save default values on empty fields. + $form['actions']['submit']['#submit'][] = 'better_formats_field_config_edit_form_submit'; + } + + // If the field is a format-using text field, allow the admin to configure + // which formats are allowed here. + if ($text_processing) { + // We have to set an explicit weight here so that we can put the allowed + // formats list after it. + $bf_settings = $entity->getThirdPartySettings('better_formats') != NULL ? $entity->getThirdPartySettings('better_formats') : []; + + // Add in the better formats table. + $form['third_party_settings'] += better_formats_field_settings_form($bf_settings); + $form['third_party_settings']['#weight'] = -4; + } +} + +/** + * Build the settings form for Field API fields. + * + * @param array $bf_form + * The existing better formats settings form from the form element. + * + * @return array + * The array of better formats form items. + */ +function better_formats_field_settings_form($bf_form = []) { + $formats = filter_formats(); + // Plain Text Format should not be an option, that is a separate field type. + unset($formats['plain_text']); + + $form = []; + $form['better_formats'] = [ + '#tree' => TRUE, + '#type' => 'fieldset', + '#title' => t('Text Formats'), + '#weight' => 0, + ]; + + $allowed_options = []; + + foreach ($formats as $format) { + $allowed_options[$format->id()] = $format->label(); + } + + $allowed_toggle_default = isset($bf_form['allowed_formats_toggle']) ? $bf_form['allowed_formats_toggle'] : FALSE; + $allowed_defaults = isset($bf_form['allowed_formats']) ? $bf_form['allowed_formats'] : []; + + if (empty($allowed_defaults)) { + $allowed_defaults = array_keys($allowed_options); + } + + $form['better_formats']['allowed_formats_toggle'] = [ + '#type' => 'checkbox', + '#title' => t('Limit allowed text formats'), + '#description' => t('Check the allowed formats below. If checked available text formats can be chosen.'), + '#weight' => 1, + '#default_value' => $allowed_toggle_default, + ]; + $form['better_formats']['allowed_formats'] = [ + '#type' => 'checkboxes', + '#title' => t('Allowed formats'), + '#options' => $allowed_options, + '#description' => t('Select the text formats allowed for this field. Note that not all of these may appear on the form if a user does not have permission to use them. Warning: This affects existing content which may leave you unable to edit some fields. If that happens you must allow the format that field was saved in here.'), + '#weight' => 2, + '#default_value' => $allowed_defaults, + '#states' => [ + 'visible' => [ + ':input[name="third_party_settings[better_formats][allowed_formats_toggle]"]' => ['checked' => TRUE], + ], + ], + ]; + + $order_toggle_default = isset($bf_form['default_order_toggle']) ? $bf_form['default_order_toggle'] : FALSE; + + $form['better_formats']['default_order_toggle'] = [ + '#type' => 'checkbox', + '#title' => t('Override default order'), + '#description' => t('Override the gloabl order that will determine the default text format a user will get only on entity creation.'), + '#weight' => 3, + '#default_value' => $order_toggle_default, + ]; + $form['better_formats']['default_order_wrapper'] = [ + '#tree' => TRUE, + '#type' => 'container', + '#weight' => 4, + '#states' => [ + 'visible' => [ + ':input[name="third_party_settings[better_formats][default_order_toggle]"]' => ['checked' => TRUE], + ], + ], + ]; + + // Formats ordering table. + $form['better_formats']['default_order_wrapper']['formats'] = [ + '#type' => 'table', + '#header' => [t('Format'), t('Weight')], + '#empty' => t('There are no items yet.'), + '#tabledrag' => [ + [ + 'action' => 'order', + 'relationship' => 'sibling', + 'group' => 'format-order-weight', + ], + ], + ]; + + foreach ($formats as $id => $format) { + $default = isset($bf_form['default_order_wrapper']['formats'][$id]) ? $bf_form['default_order_wrapper']['formats'][$id] : NULL; + $weight = isset($default['weight']) ? $default['weight'] : $format->get('weight'); + + // TableDrag: Mark the table row as draggable. + $form['better_formats']['default_order_wrapper']['formats'][$id]['#attributes']['class'][] = 'draggable'; + // TableDrag: Sort the table row according to its existing/configured weight. + $form['better_formats']['default_order_wrapper']['formats'][$id]['#weight'] = $weight; + + // Some table columns containing raw markup. + $form['better_formats']['default_order_wrapper']['formats'][$id]['label'] = [ + '#markup' => $format->label(), + ]; + + // TableDrag: Weight column element. + $form['better_formats']['default_order_wrapper']['formats'][$id]['weight'] = [ + '#type' => 'weight', + '#title' => t('Weight for @title', ['@title' => $format->label()]), + '#title_display' => 'invisible', + '#default_value' => $weight, + // Classify the weight element for #tabledrag. + '#attributes' => ['class' => ['format-order-weight']], + ]; + } + + // Sort formats according to weight. + Element::children($form['better_formats']['default_order_wrapper']['formats'], TRUE); + + return $form; +} + +/** + * Submit handler for field instance edit form. + * + * Copied and slightly modifed from FieldConfigEditForm::submitForm(). + * + * @see \Drupal\field_ui\Form\FieldConfigEditForm::submitForm() + */ +function better_formats_field_config_edit_form_submit(array &$form, FormStateInterface $form_state) { + $entity = $form_state->getFormObject()->getEntity(); + $text_processing = better_formats_is_text_format($entity->getType()); + + // Only act on fields that have text processing enabled. + if ($text_processing) { + // Handle the default value. + $default_value = []; + $default_input_value = $form_state->getValue(['default_value_input', $entity->getName()]); + + if ($default_input_value != NULL) { + $default_value = $default_input_value; + } + + $entity->setDefaultValue($default_value)->save(); + } +}