<?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']])) { $soft_limit = $sub_elements[$element[$value]['#field_name']]['widget']['settings']['soft_length_limit']; $soft_min = $sub_elements[$element[$value]['#field_name']]['widget']['settings']['soft_length_minimum']; $element[$value]['#soft_length_limit'] = (isset($element[$value]['#maxlength']) && $soft_limit > $element[$value]['#maxlength']) ? $element[$value]['#maxlength'] : $soft_limit; if (isset($sub_elements[$element[$value]['#field_name']]['widget']['settings']['soft_length_style_select'])) { $soft_enhance = $sub_elements[$element[$value]['#field_name']]['widget']['settings']['soft_length_style_select']; $element[$value]['#attributes']['data-soft-length-style-select'] = $soft_enhance; } $element[$value]['#attributes']['class'][] = 'soft-length-limit'; $element[$value]['#attributes']['data-soft-length-limit'] = $soft_limit; $element[$value]['#attributes']['data-soft-length-minimum'] = $soft_min; } } 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; } }