You are here

soft_length_limit.module in Soft Length Limit 7

Same filename and directory in other branches
  1. 8 soft_length_limit.module

Soft Length Limit module

File

soft_length_limit.module
View source
<?php

/**
 * @file
 * Soft Length Limit module
 */
define('SOFT_LENGTH_LIMIT_TITLE_MAX', 'soft_length_limit_title_max');
define('SOFT_LENGTH_LIMIT_TITLE_MIN', 'soft_length_limit_title_min');
define('SOFT_LENGTH_STYLE_SELECT', 'soft_length_style_select');

/**
 * Returns the field widget or form element types that should be affected.
 *
 * @param string $usage
 *   The desired usage of the data, can be one of 'fields' or 'elements'
 *
 * @return array
 *   An array field widget or form element type names
 */
function _soft_length_limit_types($usage) {
  $return = array();
  switch ($usage) {
    case 'fields':
      $return = array(
        'text_textarea' => 'text_textarea',
        'text_textfield' => 'text_textfield',
        'text_textarea_with_summary' => 'text_textarea_with_summary',
      );
      break;
    case 'elements':
      $return = array(
        'textarea' => 'textarea',
        'textfield' => 'textfield',
        'text_format' => 'text_format',
      );
      break;
    case 'entity_types':
      $return = array(
        'node' => 'node',
      );
      break;
  }
  return $return;
}

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Adds soft length limit fields when editing a content type.
 */
function soft_length_limit_form_node_type_form_alter(&$form, &$form_state, $form_id) {
  $form['submission'][SOFT_LENGTH_LIMIT_TITLE_MAX] = array(
    '#type' => 'textfield',
    '#title' => t('Soft length limit'),
    '#default_value' => variable_get(SOFT_LENGTH_LIMIT_TITLE_MAX . '_' . $form['#node_type']->type, NULL),
    '#description' => t('If any value is given here, a counter will appear next to this field, informing the user of the chosen number of allowed characters. If the number is exceeded, a warning will be shown.'),
    '#element_validate' => array(
      'element_validate_integer_positive',
    ),
    '#weight' => -2,
  );
  $form['submission'][SOFT_LENGTH_LIMIT_TITLE_MIN] = array(
    '#type' => 'textfield',
    '#title' => t('Soft length minimum'),
    '#default_value' => variable_get(SOFT_LENGTH_LIMIT_TITLE_MIN . '_' . $form['#node_type']->type, NULL),
    '#description' => t('If any value is given here, the minimum number recommended characters will be displayed as the editor enters text in this field.'),
    '#element_validate' => array(
      'element_validate_integer_positive',
    ),
    '#weight' => -1,
  );
  $form['submission'][SOFT_LENGTH_STYLE_SELECT] = array(
    '#type' => 'checkbox',
    '#title' => t('Enable enhanced view'),
    '#default_value' => variable_get(SOFT_LENGTH_STYLE_SELECT . '_' . $form['#node_type']->type, NULL),
    '#description' => t('Check this to enable an enhanced view of soft length states.'),
    '#weight' => -1,
  );
  $form['submission']['title_label']['#weight'] = -3;

  // Add a custom submit handler to validate that the editor didn't set the
  // maximum length to greater than 255 characters.
  $form['#validate'][] = 'soft_length_limit_validate_title_length';

  // Add a custom submit handler to save the title maximum and minimum.
  $form['#submit'][] = 'soft_length_limit_set_title_maxlength';
}

/**
 * Form validate handler for title length fields.
 */
function soft_length_limit_validate_title_length($form, &$form_state) {
  if ($form_state['values'][SOFT_LENGTH_LIMIT_TITLE_MAX] < 0 || $form_state['values'][SOFT_LENGTH_LIMIT_TITLE_MAX] > 255) {
    form_set_error('title_length', t('The value for soft length limit must be a whole number greater than zero and less than 256'), NULL);
  }
  if ($form_state['values'][SOFT_LENGTH_LIMIT_TITLE_MIN] < 0 || $form_state['values'][SOFT_LENGTH_LIMIT_TITLE_MIN] > 255) {
    form_set_error('soft_length_minimum', t('The value for soft length minimum must be a whole number greater than zero and less than 256'));
  }
  if ($form_state['values'][SOFT_LENGTH_LIMIT_TITLE_MAX] < $form_state['values'][SOFT_LENGTH_LIMIT_TITLE_MIN]) {
    form_set_error('soft_length_minimum', t('The value for soft length minimum must be less than or equal to the soft length limit'));
  }
}

/**
 * Save the values of max and minimum for title.
 * 
 * So they can be applied later as an override to #maxlength.
 */
function soft_length_limit_set_title_maxlength($form, &$form_state) {
  variable_set(SOFT_LENGTH_LIMIT_TITLE_MAX . '_' . $form_state['values']['type'], $form_state['values'][SOFT_LENGTH_LIMIT_TITLE_MAX]);
  variable_set(SOFT_LENGTH_LIMIT_TITLE_MIN . '_' . $form_state['values']['type'], $form_state['values'][SOFT_LENGTH_LIMIT_TITLE_MIN]);
  variable_set(SOFT_LENGTH_STYLE_SELECT . '_' . $form_state['values']['type'], $form_state['values'][SOFT_LENGTH_STYLE_SELECT]);
}

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Adds soft length limit fields when a field form field is rendered.
 */
function soft_length_limit_form_field_ui_field_edit_form_alter(&$form, &$form_state) {
  $types = _soft_length_limit_types('fields');
  if (isset($types[$form['#instance']['widget']['type']])) {
    $form['instance']['widget']['settings']['soft_length_limit'] = array(
      '#type' => 'textfield',
      '#title' => t('Soft length limit'),
      '#default_value' => isset($form['#instance']['widget']['settings']['soft_length_limit']) ? $form['#instance']['widget']['settings']['soft_length_limit'] : NULL,
      '#description' => t('If any value is given here, a counter will appear next to this field, informing the user of the chosen number of allowed characters. If the number is exceeded, a warning will be shown.'),
      '#element_validate' => array(
        'element_validate_integer_positive',
      ),
      '#weight' => -3,
    );
    $form['instance']['widget']['settings']['soft_length_minimum'] = array(
      '#type' => 'textfield',
      '#title' => t('Soft length minimum'),
      '#default_value' => isset($form['#instance']['widget']['settings']['soft_length_minimum']) ? $form['#instance']['widget']['settings']['soft_length_minimum'] : NULL,
      '#description' => t('If any value is given here, the minimum number recommended characters will be displayed as the editor enters text in this field.'),
      '#element_validate' => array(
        'element_validate_integer_positive',
      ),
      '#weight' => -2,
    );
    $form['instance']['widget']['settings']['soft_length_style_select'] = array(
      '#type' => 'checkbox',
      '#title' => t('Enable enhanced view'),
      '#default_value' => isset($form['#instance']['widget']['settings']['soft_length_style_select']) ? $form['#instance']['widget']['settings']['soft_length_style_select'] : 0,
      '#description' => t('Check this to enable an enhanced view of soft length states.'),
      '#weight' => -1,
    );
  }
}

/**
 * Implements hook_field_attach_form().
 */
function soft_length_limit_field_attach_form($entity_type, $entity, &$form, &$form_state, $langcode) {
  $entity_types = _soft_length_limit_types('entity_types');
  if (!isset($entity_types[$entity_type])) {
    return;
  }
  $fields = field_info_instances($entity_type, $form['#bundle']);
  $elements = array();
  foreach ($fields as $key => $value) {
    if (isset($value['widget']['settings']['soft_length_limit']) && $value['widget']['settings']['soft_length_limit'] > 0) {
      $elements[$key] = $value;
    }
  }
  if (count($elements) || isset($form['title'])) {
    soft_length_limit_set_attr($form, $elements);

    // Adds the javascript and CSS files as form attachments, in case the init
    // hook does not add them due to the context or settings.
    $form['#attached']['js'][] = drupal_get_path('module', 'soft_length_limit') . '/jquery.textchange.min.js';
    $form['#attached']['js'][] = drupal_get_path('module', 'soft_length_limit') . '/soft_length_limit.js';
    $form['#attached']['css'][] = drupal_get_path('module', 'soft_length_limit') . '/soft_length_limit.css';
  }
}

/**
 * Recurse through form and set variables.
 *
 * Recursive helper function that sets the correct attributes for the form
 * elements with a specific soft limit specified, and continues through child
 * elements.
 *
 * @param array $element
 *   The form element to iterate through
 *
 * @param array $sub_elements
 *   Array of the elements which should have a soft limit attribute
 */
function soft_length_limit_set_attr(&$element, $sub_elements) {
  $children = element_get_visible_children($element);
  $types = _soft_length_limit_types('elements');
  foreach ($children as $value) {
    if (isset($element[$value]['#type']) && isset($types[$element[$value]['#type']])) {
      if (isset($element[$value]['#field_name']) && isset($sub_elements[$element[$value]['#field_name']])) {
        $widget_settings = isset($sub_elements[$element[$value]['#field_name']]['widget']['settings']) ? $sub_elements[$element[$value]['#field_name']]['widget']['settings'] : FALSE;
        if ($widget_settings) {

          // Soft limit length.
          $soft_limit = $widget_settings['soft_length_limit'];
          $element[$value]['#soft_length_limit'] = isset($element[$value]['#maxlength']) && $soft_limit > $element[$value]['#maxlength'] ? $element[$value]['#maxlength'] : $soft_limit;
          $element[$value]['#attributes']['data-soft-length-limit'] = $soft_limit;
          $element[$value]['#attributes']['class'][] = 'soft-length-limit';

          // Soft minimum.
          $soft_min = isset($widget_settings['soft_length_minimum']) ? $widget_settings['soft_length_minimum'] : '';
          $element[$value]['#attributes']['data-soft-length-minimum'] = $soft_min;

          // Length style select.
          if (isset($widget_settings['soft_length_style_select'])) {
            $element[$value]['#attributes']['data-soft-length-style-select'] = $widget_settings['soft_length_style_select'];
          }
        }
      }
    }
    soft_length_limit_set_attr($element[$value], $sub_elements);
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Adds CSS and JS to display soft_length_limits when they are set for the
 * title field.
 */
function soft_length_limit_form_node_form_alter(&$form, $form_state) {
  $type = $form['#node']->type;
  $max_length = variable_get(SOFT_LENGTH_LIMIT_TITLE_MAX . '_' . $type, NULL);
  $min_length = variable_get(SOFT_LENGTH_LIMIT_TITLE_MIN . '_' . $type, NULL);
  if (!$min_length) {
    $min_length = 0;
  }
  $style_select = variable_get(SOFT_LENGTH_STYLE_SELECT . '_' . $type, NULL);

  // Play nice with title module ensuring that core's title is present.
  if (isset($form['title']) && (!empty($max_length) || !empty($min_length))) {
    $form['title']['#attributes']['class'][] = 'soft-length-limit';
    $form['title']['#attributes']['data-soft-length-limit'] = $max_length;
    $form['title']['#attributes']['data-soft-length-minimum'] = $min_length;
    $form['#attached']['js'][] = drupal_get_path('module', 'soft_length_limit') . '/jquery.textchange.min.js';
    $form['#attached']['js'][] = drupal_get_path('module', 'soft_length_limit') . '/soft_length_limit.js';
    $form['#attached']['css'][] = drupal_get_path('module', 'soft_length_limit') . '/soft_length_limit.css';
    $form['title']['#attributes']['data-soft-length-style-select'] = $style_select;
  }
}

Functions

Namesort descending Description
soft_length_limit_field_attach_form Implements hook_field_attach_form().
soft_length_limit_form_field_ui_field_edit_form_alter Implements hook_form_FORM_ID_alter().
soft_length_limit_form_node_form_alter Implements hook_form_FORM_ID_alter().
soft_length_limit_form_node_type_form_alter Implements hook_form_FORM_ID_alter().
soft_length_limit_set_attr Recurse through form and set variables.
soft_length_limit_set_title_maxlength Save the values of max and minimum for title.
soft_length_limit_validate_title_length Form validate handler for title length fields.
_soft_length_limit_types Returns the field widget or form element types that should be affected.

Constants