123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413 |
- <?php
- /**
- * @file
- * Enhances Drupal's core text format settings.
- */
- /**
- * Implements of hook_perm().
- */
- function better_formats_permission() {
- $entities = entity_get_info();
- $perms = array(
- 'show format tips' => array(
- 'title' => t('Show format tips'),
- 'description' => t('Toggle display of format description help.'),
- ),
- 'show more format tips link' => array(
- 'title' => t('Show more format tips link'),
- 'description' => t('Toggle display of the "More information about text formats" link.'),
- ),
- );
- foreach ($entities as $type => $info) {
- if ($info['fieldable']) {
- $perms['show format selection for ' . $type] = array(
- 'title' => t('Show format selection for @entitys', array('@entity' => $type)),
- );
- }
- }
- return $perms;
- }
- /**
- * Implements hook_menu().
- */
- function better_formats_menu() {
- $items = array();
- $items['admin/config/content/formats/settings'] = array(
- 'title' => 'Settings',
- 'description' => 'Manage text formats',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('better_formats_admin_settings_form'),
- 'access arguments' => array('administer filters'),
- 'type' => MENU_LOCAL_TASK,
- 'weight' => 3,
- 'file' => 'better_formats.admin_settings.inc',
- );
- /*
- $items['admin/config/content/formats/defaults'] = array(
- 'title' => 'Defaults',
- 'description' => 'Manage text formats',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('better_formats_defaults_admin_form'),
- 'access arguments' => array('administer filters'),
- 'type' => MENU_LOCAL_TASK,
- 'weight' => 2,
- 'file' => 'better_formats.admin_defaults.inc',
- );
- */
- return $items;
- }
- /**
- * Implements of hook_element_info_alter().
- */
- function better_formats_element_info_alter(&$type) {
- // Our process callback must run immediately after filter_process_format().
- $filter_process_format_location = array_search('filter_process_format', $type['text_format']['#process']);
- $replacement = array('filter_process_format', 'better_formats_filter_process_format');
- array_splice($type['text_format']['#process'], $filter_process_format_location, 1, $replacement);
- }
- /**
- * 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 filter_process_format()
- */
- function better_formats_filter_process_format($element) {
- // Before we make any modifications to the element, record whether or not
- // filter_process_format() 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']['#access']) && !$element['format']['#access'];
- // Now hide several parts of the element for cosmetic reasons (depending on
- // the permissions of the current user).
- $show_selection = TRUE;
- if (isset($element['#entity_type'])) {
- $show_selection = user_access('show format selection for ' . $element['#entity_type']);
- }
- $show_tips = user_access('show format tips');
- $show_tips_link = user_access('show more format tips link');
- if (!$show_selection) {
- $element['format']['format']['#access'] = FALSE;
- }
- if (!$show_tips) {
- $element['format']['guidelines']['#access'] = FALSE;
- }
- if (!$show_tips_link) {
- $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 filter_process_format() 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 (isset($element['#entity_type']) && !$access_denied_for_security) {
- $instance_info = field_info_instance($element['#entity_type'], $element['#field_name'], $element['#bundle']);
- $bf = isset($instance_info['settings']['better_formats']) ? $instance_info['settings']['better_formats'] : NULL;
- // Need to only do this on create forms.
- if (!empty($element['#entity']) && !empty($element['#entity_type'])) {
- list($eid, $vid, $bundle) = entity_extract_ids($element['#entity_type'], $element['#entity']);
- 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 = array();
- 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);
- $element['format']['format']['#default_value'] = 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;
- $show_selection = FALSE;
- }
- // 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);
- $element['format']['format']['#default_value'] = 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;
- $element['format']['format']['#default_value'] = 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 (!$show_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;
- }
- }
- }
- // Hide the entire text format fieldset if the user is not supposed to see
- // anything inside it.
- if (!$show_selection && !$show_tips && !$show_tips_link) {
- $element['format']['#type'] = 'container';
- }
- return $element;
- }
- /**
- * Sort text formats by weight.
- */
- function better_formats_text_format_sort($a, $b) {
- return $a['weight'] > $b['weight'];
- }
- /**
- * Implements hook_form_FORM_ID_alter().
- */
- function better_formats_form_field_ui_field_edit_form_alter(&$form, &$form_state, $form_id) {
- $settings = $form['#instance']['settings'];
- // Only alter fields with text processing and if admin has chosen.
- $text_processing = isset($settings['text_processing']);
- if ($text_processing && variable_get('better_formats_per_field_core', 0)) {
- // Add a submit handler to save default values on empty fields.
- $form['#submit'][] = 'better_formats_form_field_ui_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.
- $form['instance']['settings']['text_processing']['#weight'] = -3;
- $bf_settings = isset($settings['better_formats']) ? $settings['better_formats'] : array();
- // Add in our formats table
- $form['instance']['settings'] += better_formats_field_settings_form($bf_settings);
- }
- }
- /**
- * Build the settings form for Field API fields.
- *
- * @param $bf_form
- * The existing better formats settings form from the form element.
- */
- function better_formats_field_settings_form($bf_form = array()) {
- $formats = filter_formats();
- $form = array();
- $form['better_formats'] = array(
- '#tree' => TRUE,
- '#type' => 'fieldset',
- '#title' => t('Text Formats'),
- '#weight' => -2,
- '#states' => array(
- 'visible' => array(
- ':input[name="instance[settings][text_processing]"]' => array('value' => '1'),
- ),
- ),
- );
- foreach ($formats as $format_id => $format) {
- $allowed_options[$format_id] = $format->name;
- }
- $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'] : array();
- if (empty($allowed_defaults)) {
- $allowed_defaults = array_keys($allowed_options);
- }
- $form['better_formats']['allowed_formats_toggle'] = array(
- '#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'] = array(
- '#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. <strong>Warning:</strong> 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' => array(
- 'visible' => array(
- ':input[name="instance[settings][text_processing]"]' => array('value' => '1'),
- ':input[name="instance[settings][better_formats][allowed_formats_toggle]"]' => array('checked' => TRUE),
- ),
- ),
- );
- $order_toggle_default = isset($bf_form['default_order_toggle']) ? $bf_form['default_order_toggle'] : FALSE;
- $form['better_formats']['default_order_toggle'] = array(
- '#type' => 'checkbox',
- '#title' => t('Override default order'),
- '#description' => t('Override the global order that will determine the default text format a user will get <strong>only on entity creation</strong>.'),
- '#weight' => 3,
- '#default_value' => $order_toggle_default,
- );
- $form['better_formats']['default_order_wrapper'] = array(
- //'#tree' => TRUE,
- '#type' => 'container',
- '#theme' => 'better_formats_field_default_order',
- '#weight' => 4,
- '#states' => array(
- 'visible' => array(
- ':input[name="instance[settings][text_processing]"]' => array('value' => '1'),
- ':input[name="instance[settings][better_formats][default_order_toggle]"]' => array('checked' => TRUE),
- ),
- ),
- );
- foreach ($formats as $key => $format) {
- $default = isset($bf_form['default_order_wrapper']['formats'][$key]) ? $bf_form['default_order_wrapper']['formats'][$key] : NULL;
- $rows[$key]['name'] = array('#markup' => $format->name);
- $rows[$key]['weight'] = array(
- '#type' => 'weight',
- '#default_value' => isset($default['weight']) ? $default['weight'] : $format->weight,
- '#delta' => 50,
- );
- $rows[$key]['#weight'] = isset($default['weight']) ? $default['weight'] : $format->weight;
- }
- $form['better_formats']['default_order_wrapper']['formats'] = $rows;
- return $form;
- }
- /**
- * Submit handler for field instance edit form.
- *
- * Copied and slightly modifed from field_ui_field_edit_form_submit().
- * @see field_ui_field_edit_form_submit()
- */
- function better_formats_form_field_ui_edit_form_submit($form, &$form_state) {
- $instance = $form_state['values']['instance'];
- $field = $form_state['values']['field'];
- // Only act on fields that have text processing enabled.
- if ($instance['settings']['text_processing'] == 1) {
- // Update any field settings that have changed.
- $field_source = field_info_field($instance['field_name']);
- $field = array_merge($field_source, $field);
- field_update_field($field);
- // Handle the default value.
- if (isset($form['instance']['default_value_widget'])) {
- $element = $form['instance']['default_value_widget'];
- // Extract field values.
- $items = array();
- field_default_extract_form_values(NULL, NULL, $field, $instance, LANGUAGE_NONE, $items, $element, $form_state);
- // Commenting out the below line to not remove emtpy fields.
- //field_default_submit(NULL, NULL, $field, $instance, LANGUAGE_NONE, $items, $element, $form_state);
- $instance['default_value'] = $items ? $items : NULL;
- }
- // Retrieve the stored instance settings to merge with the incoming values.
- $instance_source = field_read_instance($instance['entity_type'], $instance['field_name'], $instance['bundle']);
- $instance = array_merge($instance_source, $instance);
- field_update_instance($instance);
- }
- // Messaging and redirect removed as this is added in the default handler.
- }
- /**
- * Implements hook_theme()
- */
- function better_formats_theme() {
- return array(
- 'better_formats_field_default_order' => array(
- 'render element' => 'form',
- )
- );
- }
- /**
- * Theme format default by role on field settings form.
- */
- function theme_better_formats_field_default_order(&$variables) {
- $form = $variables['form'];
- $rows = array();
- $output = drupal_render($form['override']);
- if (is_array($form)) {
- $order_form =& $form['formats'];
- $order_form['#sorted'] = FALSE;
- foreach (element_children($order_form, TRUE) as $name) {
- $order_form[$name]['weight']['#attributes']['class'][] = 'format-order-weight';
- $rows[] = array(
- 'data' => array(
- drupal_render($order_form[$name]['name']),
- drupal_render($order_form[$name]['weight']),
- ),
- 'class' => array('draggable'),
- );
- }
- }
- $header = array(
- t('Format'),
- t('Weight'),
- );
- $output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'format-order')));
- drupal_add_tabledrag('format-order', 'order', 'sibling', 'format-order-weight', NULL, NULL, TRUE);
- return $output;
- }
|