TRUE, '#tree' => TRUE, '#pre_render' => array('form_pre_render_conditional_form_element'), '#value_callback' => 'commerce_file_limit_integer_element_value', '#process' => array('commerce_file_limit_integer_element_process'), '#element_validate' => array('commerce_file_limit_integer_element_validate'), '#limit_inherited_value' => NULL, '#default_value' => array( 'mode' => COMMERCE_FILE_LIMIT_UNLIMITED, 'value' => '', ), ); // A limit duration form element which represents the duration in seconds. $types['commerce_file_limit_duration'] = array( '#input' => TRUE, '#tree' => TRUE, '#pre_render' => array('form_pre_render_conditional_form_element'), '#value_callback' => 'commerce_file_limit_duration_element_value', '#process' => array('commerce_file_limit_duration_element_process'), '#element_validate' => array('commerce_file_limit_duration_element_validate'), '#limit_inherited_value' => NULL, '#default_value' => array( 'mode' => COMMERCE_FILE_LIMIT_UNLIMITED, 'value' => '', ), ); return $types; } /** * Return keyed array of limit mode options */ function _commerce_file_limit_element_get_mode_options($element, $inherited_format_callback = '') { $options = array( COMMERCE_FILE_LIMIT_UNLIMITED => t('Unlimited'), 'value' => t('Custom value'), ); // prepend inherited option if (isset($element['#limit_inherited_value'])) { $inherited_value = $element['#limit_inherited_value']; if (!empty($inherited_format_callback)) { $inherited_value = $inherited_format_callback($inherited_value); } $options = array( COMMERCE_FILE_LIMIT_INHERITED => t('Inherited (@inherited)', array('@inherited' => $inherited_value)), ) + $options; } return $options; } // ----------------------------------------------------------------------- // Limit Textfield /** * FAPI process callback for limit textfield element type. */ function commerce_file_limit_integer_element_process($element, &$form_state) { // Put the child elements in a container div. $element['#prefix'] = isset($element['#field_prefix']) ? $element['#field_prefix'] : ''; $element['#prefix'] = '
' . $element['#prefix']; unset($element['#field_prefix']); // move description to the top if (isset($element['#description'])) { $element['description'] = array( '#markup' => '
' . $element['#description'] . '
', '#weight' => -10, ); unset($element['#description']); } // close container $element['#suffix'] = isset($element['#field_suffix']) ? $element['#field_suffix'] : ''; $element['#suffix'] .= '
'; unset($element['#field_suffix']); // attach css $element['#attached']['css'][] = drupal_get_path('module', 'commerce_file') . '/css/commerce_file.forms.css'; // build limit mode and value $element['#mode_options'] = _commerce_file_limit_element_get_mode_options($element); $defaults = _commerce_file_limit_element_get_defaults($element); $element['mode'] = array( '#type' => 'radios', '#options' => $element['#mode_options'], '#default_value' => $defaults['mode'], '#attributes' => array('class' => array('commerce-file-limit-element-mode')), ); $element['value'] = array( '#type' => 'textfield', '#size' => 10, '#default_value' => $defaults['value'], '#attributes' => array('class' => array('commerce-file-limit-element-value')), '#states' => array( 'visible' => array( ':input[name="' . $element['#name'] . '[mode]"]' => array('value' => 'value'), ), ), ); return $element; } /** * FAPI element validate callback for limit textfield element type. */ function commerce_file_limit_integer_element_validate($element, &$form_state) { $data = $element['#value']; $value = NULL; if (empty($data)) { return; } if ($data['mode'] == 'value') { // process entered value $value = $data['value']; // validate as not empty here since #required on value would require for all modes if (_commerce_file_element_value_is_empty($value)) { form_error($element, t('%name field is required.', array('%name' => $element['#title']))); return; } // validate as positive integer or 0 if (!_commerce_file_is_integer_or_zero($value)) { form_error($element, t('%name must be a positive integer or zero.', array('%name' => $element['#title']))); return; } // ensure integer value stored $value = intval($value); } else { // set value to the mode key $value = $data['mode']; } // Consolidate into one value. form_set_value($element, $value, $form_state); } /** * FAPI value callback for limit textfield element type. */ function commerce_file_limit_integer_element_value($element, $input = FALSE, $form_state = array()) { return _commerce_file_limit_element_value($element, $input, $form_state); } // ----------------------------------------------------------------------- // Limit Duration /** * FAPI process callback for limit textfield element type. */ function commerce_file_limit_duration_element_process($element, &$form_state) { // Put the child elements in a container div. $element['#prefix'] = isset($element['#field_prefix']) ? $element['#field_prefix'] : ''; $element['#prefix'] = '
' . $element['#prefix']; unset($element['#field_prefix']); // move description to the top if (isset($element['#description'])) { $element['description'] = array( '#markup' => '
' . $element['#description'] . '
', '#weight' => -10, ); unset($element['#description']); } // close container $element['#suffix'] = isset($element['#field_suffix']) ? $element['#field_suffix'] : ''; $element['#suffix'] .= '
'; unset($element['#field_suffix']); // attach css $element['#attached']['css'][] = drupal_get_path('module', 'commerce_file') . '/css/commerce_file.forms.css'; // build limit mode and value $element['#mode_options'] = _commerce_file_limit_element_get_mode_options($element, 'format_interval'); $defaults = _commerce_file_limit_element_get_defaults($element); $element['mode'] = array( '#type' => 'radios', '#options' => $element['#mode_options'], '#default_value' => $defaults['mode'], '#attributes' => array('class' => array('commerce-file-limit-element-mode')), ); $default_value = NULL; $default_unit = 86400; if (isset($defaults['value'])) { // split into value and unit of greatest divisor list($default_value, $default_unit) = _commerce_file_limit_duration_element_explode_value($defaults['value']); } $element['value'] = array( '#type' => 'container', 'value' => array( '#type' => 'textfield', '#size' => 10, '#default_value' => $default_value, '#element_validate' => array('_commerce_file_element_validate_integer_positive_or_zero'), ), 'unit' => array( '#type' => 'select', '#default_value' => $default_unit, '#options' => _commerce_file_limit_duration_element_units(), ), 'description' => array( '#markup' => '
' . t('Enter an integer value or zero.
Months are based on 30 days.') . '
', ), '#attributes' => array('class' => array('commerce-file-limit-element-value container-inline')), '#states' => array( 'visible' => array( ':input[name="' . $element['#name'] . '[mode]"]' => array('value' => 'value'), ), ), ); return $element; } /** * FAPI element validate callback for limit integer element type. */ function commerce_file_limit_duration_element_validate($element, &$form_state) { $data = $element['#value']; $value = NULL; if (empty($data)) { return; } if ($data['mode'] == 'value') { // process entered value $duration = $data['value']; // validate as not empty here since #required on value would require for all modes if (!isset($duration['value']) || _commerce_file_element_value_is_empty($duration['value'])) { form_error($element, t('%name field is required.', array('%name' => $element['#title']))); return; } // set seconds to store $value = $duration['value']; if (!empty($duration['unit'])) { $value *= $duration['unit']; } // ensure integer value stored $value = intval($value); } else { // set value to the mode key $value = $data['mode']; } // Consolidate into one value. form_set_value($element, $value, $form_state); } /** * FAPI value callback for limit duration element type. */ function commerce_file_limit_duration_element_value($element, $input = FALSE, $form_state = array()) { return _commerce_file_limit_element_value($element, $input, $form_state); } /** * Defines possible duration multipliers. */ function _commerce_file_limit_duration_element_units() { $units = &drupal_static(__FUNCTION__); if (!isset($units)) { $units = array( 365*86400 => t('years'), 30*86400 => t('months'), 7*86400 => t('weeks'), 86400 => t('days'), 3600 => t('hours'), 60 => t('minutes'), 1 => t('seconds'), ); } return $units; } /** * Returns an array of scalar value, greatest unit multiplier */ function _commerce_file_limit_duration_element_explode_value($value) { if (!is_scalar($value)) { return array(); } $unit = _commerce_file_limit_duration_element_greatest_unit($value); return array($value / $unit, $unit); } /** * Returns the greatest unit multiplier that yields an integer value */ function _commerce_file_limit_duration_element_greatest_unit($value) { $units = _commerce_file_limit_duration_element_units(); foreach ($units as $multiplier => $label) { if ($multiplier && ($value % $multiplier == 0)) { return $multiplier; } } // fallback to seconds return 1; } // ----------------------------------------------------------------------- // Limit Helpers /** * FAPI value callback for limit element types. */ function _commerce_file_limit_element_value($element, $input = FALSE, $form_state = array()) { if ($input !== FALSE) { return $input; } $return = array(); $mode_options = _commerce_file_limit_element_get_mode_options($element); $default_value = isset($element['#default_value']) ? $element['#default_value'] : COMMERCE_FILE_LIMIT_UNLIMITED; if (is_scalar($default_value) && isset($mode_options[$default_value])) { $return['mode'] = $default_value; $return['value'] = ''; } else { $return['mode'] = 'value'; $return['value'] = $default_value; } return $return; } /** * Returns an array of defaults for the given element */ function _commerce_file_limit_element_get_defaults($element) { $defaults = array('mode' => COMMERCE_FILE_LIMIT_UNLIMITED, 'value' => NULL); if (isset($element['#default_value'])) { if (is_array($element['#default_value'])) { $defaults = $element['#default_value'] + $defaults; } elseif (isset($element['#mode_options'][$element['#default_value']])) { $defaults['mode'] = $element['#default_value']; } else { $defaults['mode'] = 'value'; $defaults['value'] = $element['#default_value']; } } return $defaults; } /** * Returns TRUE if the limit is inherited */ function _commerce_file_limit_is_inherited($value) { return strcmp($value, COMMERCE_FILE_LIMIT_INHERITED) === 0; } /** * Returns TRUE if the limit is unlimited */ function _commerce_file_limit_is_unlimited($value) { return strcmp($value, COMMERCE_FILE_LIMIT_UNLIMITED) === 0; }