range.module in Range 7
Same filename and directory in other branches
Defines range field types.
File
range.moduleView source
<?php
/**
* @file
* Defines range field types.
*/
// Include i18n.
require_once 'range.i18n.inc';
/**
* Implements hook_field_info().
*/
function range_field_info() {
$instance_settings = array(
'min' => '',
'max' => '',
'field' => array(
'prefix' => '',
'suffix' => '',
),
'from' => array(
'label' => t('From'),
'prefix' => '',
'suffix' => '',
),
'to' => array(
'label' => t('to'),
'prefix' => '',
'suffix' => '',
),
'combined' => array(
'prefix' => '',
'suffix' => '',
),
);
return array(
'range_integer' => array(
'label' => t('Range: integer'),
'description' => t('This field stores a range in the database as an integer.'),
'instance_settings' => $instance_settings,
'default_widget' => 'range',
'default_formatter' => 'range_integer',
'property_type' => 'field_item_range',
'property_callbacks' => array(
'range_metadata_field_range_callback',
),
),
'range_decimal' => array(
'label' => t('Range: decimal'),
'description' => t('This field stores a range in the database in a fixed decimal format.'),
'settings' => array(
'precision' => 10,
'scale' => 2,
'decimal_separator' => '.',
),
'instance_settings' => $instance_settings,
'default_widget' => 'range',
'default_formatter' => 'range_decimal',
'property_type' => 'field_item_range',
'property_callbacks' => array(
'range_metadata_field_range_callback',
),
),
'range_float' => array(
'label' => t('Range: float'),
'description' => t('This field stores a range in the database in a floating point format.'),
'settings' => array(
'decimal_separator' => '.',
),
'instance_settings' => $instance_settings,
'default_widget' => 'range',
'default_formatter' => 'range_decimal',
'property_type' => 'field_item_range',
'property_callbacks' => array(
'range_metadata_field_range_callback',
),
),
);
}
/**
* Implements hook_field_settings_form().
*/
function range_field_settings_form($field, $instance, $has_data) {
$settings = $field['settings'];
$form = array();
if ($field['type'] === 'range_decimal') {
$form['precision'] = array(
'#type' => 'select',
'#title' => t('Precision'),
'#options' => drupal_map_assoc(range(10, 32)),
'#default_value' => $settings['precision'],
'#description' => t('The total number of digits to store in the database, including those to the right of the decimal.'),
'#disabled' => $has_data,
);
$form['scale'] = array(
'#type' => 'select',
'#title' => t('Scale'),
'#options' => drupal_map_assoc(range(0, 10)),
'#default_value' => $settings['scale'],
'#description' => t('The number of digits to the right of the decimal.'),
'#disabled' => $has_data,
);
}
if ($field['type'] === 'range_decimal' || $field['type'] === 'range_float') {
$form['decimal_separator'] = array(
'#type' => 'select',
'#title' => t('Decimal marker'),
'#options' => array(
'.' => t('Decimal point'),
',' => t('Comma'),
),
'#default_value' => $settings['decimal_separator'],
'#description' => t('The character users will input to mark the decimal point in forms.'),
);
}
return $form;
}
/**
* Implements hook_field_instance_settings_form().
*/
function range_field_instance_settings_form($field, $instance) {
$settings = $instance['settings'];
$form['min'] = array(
'#type' => 'textfield',
'#title' => t('Minimum'),
'#default_value' => $settings['min'],
'#description' => t('The minimum value that should be allowed in this field. Leave blank for no minimum.'),
'#element_validate' => array(
'element_validate_number',
),
);
$form['max'] = array(
'#type' => 'textfield',
'#title' => t('Maximum'),
'#default_value' => $settings['max'],
'#description' => t('The maximum value that should be allowed in this field. Leave blank for no maximum.'),
'#element_validate' => array(
'element_validate_number',
),
);
_range_field_instance_subelements_settings_form($form, 'from', $settings);
_range_field_instance_subelements_settings_form($form, 'to', $settings);
_range_field_instance_subelements_settings_form($form, 'field', $settings);
_range_field_instance_subelements_settings_form($form, 'combined', $settings);
return $form;
}
/**
* Helper function. Builds settings fieldsets for the FROM/TO subelements.
*
* @param array $form
* Instance settings form definition array.
* @param string $name
* Form element machine name.
* @param array $settings
* Field instance settings.
*/
function _range_field_instance_subelements_settings_form(array &$form, $name, array $settings) {
$form[$name] = array(
'#type' => 'fieldset',
'#title' => drupal_ucfirst($name) . ' value',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
if ($name === 'from' || $name === 'to') {
$form[$name]['label'] = array(
'#type' => 'textfield',
'#title' => t('Form element label'),
'#default_value' => $settings[$name]['label'],
'#description' => t('Defines label for form element.'),
);
}
$form[$name]['prefix'] = array(
'#type' => 'textfield',
'#title' => t('Prefix'),
'#default_value' => $settings[$name]['prefix'],
'#size' => 60,
'#description' => t("Define a string that should be prefixed to the value, like '\$ ' or '€ '. Leave blank for none."),
);
$form[$name]['suffix'] = array(
'#type' => 'textfield',
'#title' => t('Suffix'),
'#default_value' => $settings[$name]['suffix'],
'#size' => 60,
'#description' => t("Define a string that should be suffixed to the value, like ' m', ' kb/s'. Leave blank for none."),
);
}
/**
* Implements hook_field_validate().
*
* Possible error codes:
* - 'range_both_required': Both FROM and TO values must be specified.
* - 'range_min': The FROM value is less than the allowed minimum value.
* - 'range_max': The TO value is greater than the allowed maximum value.
* - 'range_from_greater_than_to': FROM value is greater than TO value.
*/
function range_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
$instance = range_translate_field_instance($instance);
foreach ($items as $delta => $item) {
if ($item['from'] !== '' && $item['to'] === '' || $item['from'] === '' && $item['to'] !== '') {
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => 'range_both_required',
'message' => t('%name: you must specify two values.', array(
'%name' => $instance['label'],
)),
);
}
if ($item['from'] != '' && $item['to'] != '') {
if (is_numeric($instance['settings']['min']) && $item['from'] < $instance['settings']['min']) {
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => 'range_min',
'message' => t('%name: the FROM value may be no less than %min.', array(
'%name' => $instance['label'],
'%min' => $instance['settings']['min'],
)),
);
}
if ($item['from'] > $item['to']) {
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => 'range_from_greater_than_to',
'message' => t('%name: FROM value is greater than TO value.', array(
'%name' => $instance['label'],
)),
);
}
if (is_numeric($instance['settings']['max']) && $item['to'] > $instance['settings']['max']) {
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => 'range_max',
'message' => t('%name: the TO value may be no greater than %max.', array(
'%name' => $instance['label'],
'%max' => $instance['settings']['max'],
)),
);
}
}
}
}
/**
* Implements hook_field_presave().
*/
function range_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
if ($field['type'] === 'range_decimal') {
// Let PHP round the value to ensure consistent behavior across storage
// backends.
foreach ($items as $delta => $item) {
if (isset($item['from'])) {
$items[$delta]['from'] = round($item['from'], $field['settings']['scale']);
}
if (isset($item['to'])) {
$items[$delta]['to'] = round($item['to'], $field['settings']['scale']);
}
}
}
}
/**
* Implements hook_field_is_empty().
*/
function range_field_is_empty($item, $field) {
if (empty($item['from']) && (string) $item['from'] !== '0' && empty($item['to']) && (string) $item['to'] !== '0') {
return TRUE;
}
return FALSE;
}
/**
* Implements hook_field_formatter_info().
*/
function range_field_formatter_info() {
$base_settings = array(
'range_combine' => FALSE,
'range_separator' => '-',
'from_prefix_suffix' => TRUE,
'to_prefix_suffix' => TRUE,
'field_prefix_suffix' => TRUE,
'combined_prefix_suffix' => FALSE,
);
$base_number_format_settings = array(
'thousand_separator' => ' ',
'decimal_separator' => '.',
);
return array(
'range_integer' => array(
'label' => t('Default'),
'field types' => array(
'range_integer',
),
'settings' => $base_settings + $base_number_format_settings + array(
'scale' => 0,
),
),
'range_decimal' => array(
'label' => t('Default'),
'field types' => array(
'range_decimal',
'range_float',
),
'settings' => $base_settings + $base_number_format_settings + array(
'scale' => 2,
),
),
'range_integer_sprintf' => array(
'label' => t('Formatted string'),
'field types' => array(
'range_integer',
),
'settings' => $base_settings + array(
'format_string' => '%d',
),
),
'range_decimal_sprintf' => array(
'label' => t('Formatted string'),
'field types' => array(
'range_decimal',
'range_float',
),
'settings' => $base_settings + array(
'format_string' => '%.2f',
),
),
'range_unformatted' => array(
'label' => t('Unformatted'),
'field types' => array(
'range_integer',
'range_decimal',
'range_float',
),
'settings' => $base_settings,
),
);
}
/**
* Implements hook_field_formatter_settings_form().
*/
function range_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
$display = $instance['display'][$view_mode];
$settings = $display['settings'];
$element = array();
if ($display['type'] === 'range_decimal' || $display['type'] === 'range_integer') {
$element['thousand_separator'] = array(
'#type' => 'select',
'#title' => t('Thousand marker'),
'#options' => array(
'' => t('<none>'),
'.' => t('Decimal point'),
',' => t('Comma'),
' ' => t('Space'),
),
'#default_value' => $settings['thousand_separator'],
);
}
if ($display['type'] === 'range_decimal') {
$element['decimal_separator'] = array(
'#type' => 'select',
'#title' => t('Decimal marker'),
'#options' => array(
'.' => t('Decimal point'),
',' => t('Comma'),
', ' => t('Comma and space'),
),
'#default_value' => $settings['decimal_separator'],
);
$element['scale'] = array(
'#type' => 'select',
'#title' => t('Scale'),
'#options' => drupal_map_assoc(range(0, 10)),
'#default_value' => $settings['scale'],
'#description' => t('The number of digits to the right of the decimal.'),
);
}
if ($display['type'] === 'range_integer_sprintf' || $display['type'] === 'range_decimal_sprintf') {
$element['format_string'] = array(
'#type' => 'textfield',
'#title' => t('Format'),
'#description' => t('See <a href="!url">PHP documentation</a> for a description of format. <strong>Due to PHP limitations, thousand separator cannot be used.</strong>', array(
'!url' => 'http://php.net/manual/en/function.sprintf.php',
)),
'#default_value' => $settings['format_string'],
);
}
_range_field_formatter_base_settings_form($element, $settings, $field['field_name']);
return $element;
}
/**
* Helper function. Adds formatter base settings to the form element.
*
* @param array $element
* Form element.
* @param array $settings
* Field formatter settings.
*/
function _range_field_formatter_base_settings_form(array &$element, array $settings, $field_name) {
$element['range_separator'] = array(
'#type' => 'textfield',
'#title' => t('Range separator'),
'#default_value' => $settings['range_separator'],
);
$element['range_combine'] = array(
'#type' => 'checkbox',
'#title' => t('Combine equivalent values'),
'#description' => t('If the FROM and TO values are equal, combine the display into a single value.'),
'#default_value' => $settings['range_combine'],
);
$element['from_prefix_suffix'] = array(
'#type' => 'checkbox',
'#title' => t('Display <em>FROM value</em> prefix and suffix'),
'#default_value' => $settings['from_prefix_suffix'],
);
$element['to_prefix_suffix'] = array(
'#type' => 'checkbox',
'#title' => t('Display <em>TO value</em> prefix and suffix'),
'#default_value' => $settings['to_prefix_suffix'],
);
$element['field_prefix_suffix'] = array(
'#type' => 'checkbox',
'#title' => t('Display <em>FIELD value</em> prefix and suffix'),
'#default_value' => $settings['field_prefix_suffix'],
);
$element['combined_prefix_suffix'] = array(
'#type' => 'checkbox',
'#title' => t('Display <em>COMBINED value</em> prefix and suffix'),
'#default_value' => $settings['combined_prefix_suffix'],
'#states' => array(
'visible' => array(
':input[name="fields[' . $field_name . '][settings_edit_form][settings][range_combine]"]' => array(
'checked' => TRUE,
),
),
),
);
}
/**
* Implements hook_field_formatter_settings_summary().
*/
function range_field_formatter_settings_summary($field, $instance, $view_mode) {
$display = $instance['display'][$view_mode];
$settings = $display['settings'];
$summary = array();
$from = _range_number_format(1234.123456789, $display['type'], $settings);
$to = _range_number_format(4321.0987654321, $display['type'], $settings);
$summary[] = $from . field_filter_xss($settings['range_separator']) . $to;
_range_field_formatter_base_settings_summary($summary, $settings);
return implode('<br />', $summary);
}
/**
* Helper function. Returns summary for formatter base settings.
*
* @param array $summary
* Formatter summary.
* @param array $settings
* Field formatter settings.
*/
function _range_field_formatter_base_settings_summary(array &$summary, array $settings) {
if ($settings['range_combine']) {
$summary[] = t('Equivalent values will be combined into a single value.');
}
if ($settings['from_prefix_suffix']) {
$summary[] = t('Display with <em>FROM value</em> prefix and suffix.');
}
if ($settings['to_prefix_suffix']) {
$summary[] = t('Display with <em>TO value</em> prefix and suffix.');
}
if ($settings['field_prefix_suffix']) {
$summary[] = t('Display with <em>FIELD value</em> prefix and suffix.');
}
if ($settings['range_combine'] && $settings['combined_prefix_suffix']) {
$summary[] = t('Display with <em>COMBINED value</em> prefix and suffix.');
}
}
/**
* Implements hook_field_formatter_view().
*/
function range_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$element = array();
$settings = $display['settings'];
$instance = range_translate_field_instance($instance);
foreach ($items as $delta => $item) {
$from_value = _range_number_format($item['from'], $display['type'], $settings);
$to_value = _range_number_format($item['to'], $display['type'], $settings);
// Combine values if they are equal.
if (!empty($settings['range_combine']) && $from_value === $to_value) {
$output = _range_field_formatter_view_combined_value($from_value, $settings, $instance['settings']);
}
else {
$output = _range_field_formatter_view_separate_values($from_value, $to_value, $settings, $instance['settings']);
}
// Add field prefix/suffix.
$output = _range_field_formatter_view_prefix_suffix($output, $settings['field_prefix_suffix'], $instance['settings']['field']);
$element[$delta] = array(
'#markup' => $output,
);
}
return $element;
}
/**
* Helper function. Formats a number according to formatter settings.
*
* @param int|double $number
* Number to format.
* @param string $display_type
* Formatter being used.
* @param array $settings
* Array of formatter settings:
* - format_string: format string for sprintf() function
* - scale: number scale
* - decimal_separator: string, used as a decimal separator
* - thousand_separator: string, used as a thousand separator.
*
* @return string
* Formatted number.
*/
function _range_number_format($number, $display_type, array $settings) {
switch ($display_type) {
case 'range_integer':
case 'range_decimal':
return (string) number_format($number, $settings['scale'], $settings['decimal_separator'], $settings['thousand_separator']);
case 'range_integer_sprintf':
case 'range_decimal_sprintf':
return (string) sprintf(field_filter_xss($settings['format_string']), $number);
default:
return (string) $number;
}
}
/**
* Helper function. Returns field markup for combined value option.
*
* FROM and TO might have different prefixes/suffixes.
* Code below decides which one to use, based on the following:
* - If COMBINED is enabled - show it
* - If COMBINED is disabled and both FROM/TO are disabled - show naked value
* - If COMBINED is disabled and either FROM or TO are enabled - show
* prefix/suffix of the enabled one
* - If COMBINED is disabled and both FROM/TO are enabled, show prefix from
* FROM and suffix from TO
*
* @param string $value
* Field value.
* @param array $settings
* Display settings array.
* @param array $instance_settings
* Field instance settings array.
*
* @return string
* Field markup.
*/
function _range_field_formatter_view_combined_value($value, array $settings, array $instance_settings) {
$from_prefix_suffix = !empty($settings['from_prefix_suffix']);
$to_prefix_suffix = !empty($settings['to_prefix_suffix']);
$combined_prefix_suffix = !empty($settings['combined_prefix_suffix']);
// Option #0: COMBINED is enabled.
if ($combined_prefix_suffix) {
return _range_field_formatter_view_prefix_suffix($value, TRUE, $instance_settings['combined']);
}
elseif (empty($from_prefix_suffix) && empty($to_prefix_suffix)) {
return $value;
}
elseif (!empty($from_prefix_suffix) && empty($to_prefix_suffix)) {
return _range_field_formatter_view_prefix_suffix($value, TRUE, $instance_settings['from']);
}
elseif (empty($from_prefix_suffix) && !empty($to_prefix_suffix)) {
return _range_field_formatter_view_prefix_suffix($value, TRUE, $instance_settings['to']);
}
else {
return _range_field_formatter_view_prefix_suffix($value, TRUE, array(
'prefix' => $instance_settings['from']['prefix'],
'suffix' => $instance_settings['to']['suffix'],
));
}
}
/**
* Helper function. Returns field markup for separate values option.
*
* @param string $from_value
* Field FROM value.
* @param string $to_value
* Field TO value.
* @param array $settings
* Display settings array.
* @param array $instance_settings
* Field instance settings array.
*
* @return string
* Field markup.
*/
function _range_field_formatter_view_separate_values($from_value, $to_value, array $settings, array $instance_settings) {
$from = _range_field_formatter_view_prefix_suffix($from_value, $settings['from_prefix_suffix'], $instance_settings['from']);
$to = _range_field_formatter_view_prefix_suffix($to_value, $settings['to_prefix_suffix'], $instance_settings['to']);
return $from . field_filter_xss($settings['range_separator']) . $to;
}
/**
* Helper function. Adds prefix and suffix to the given range field value.
*
* @param string $value
* FROM/TO range field value.
* @param bool $display_prefix
* Whether to add suffix/prefix or not.
* @param array $instance_settings
* Field instance FROM/TO value settings.
*
* @return string
* Range field value with added prefix/suffix.
*/
function _range_field_formatter_view_prefix_suffix($value, $display_prefix, array $instance_settings) {
if ($display_prefix) {
$prefix = isset($instance_settings['prefix']) ? field_filter_xss($instance_settings['prefix']) : '';
$suffix = isset($instance_settings['suffix']) ? field_filter_xss($instance_settings['suffix']) : '';
return $prefix . $value . $suffix;
}
return $value;
}
/**
* Implements hook_field_widget_info().
*/
function range_field_widget_info() {
return array(
'range' => array(
'label' => t('Text fields'),
'field types' => array(
'range_integer',
'range_decimal',
'range_float',
),
),
);
}
/**
* Implements hook_field_widget_form().
*/
function range_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
$instance = range_translate_field_instance($instance);
$settings = $instance['settings'];
$from = isset($items[$delta]['from']) ? $items[$delta]['from'] : '';
$to = isset($items[$delta]['to']) ? $items[$delta]['to'] : '';
// Substitute the decimal separator.
if ($field['type'] === 'range_decimal' || $field['type'] === 'range_float') {
$from = strtr($from, '.', $field['settings']['decimal_separator']);
$to = strtr($to, '.', $field['settings']['decimal_separator']);
}
// Wrap in a fieldset for single field.
if ($field['cardinality'] == 1) {
$element['#type'] = 'fieldset';
}
$element += array(
// Extract the range type from the field type name for easier validation.
'#range_type' => str_replace('range_', '', $field['type']),
);
$base = array(
'#type' => 'textfield',
// Allow a slightly larger size that the field length to allow for some
// configurations where all characters won't fit in input field.
'#size' => $field['type'] === 'range_decimal' ? $field['settings']['precision'] + 4 : 12,
// Allow two extra characters for signed values and decimal separator.
'#maxlength' => $field['type'] === 'range_decimal' ? $field['settings']['precision'] + 2 : 10,
'#required' => $element['#required'],
);
$element['from'] = array(
'#title' => $settings['from']['label'],
'#default_value' => $from,
'#prefix' => '<div class="field-values-wrapper clearfix">',
) + $base;
$element['to'] = array(
'#title' => $settings['to']['label'],
'#default_value' => $to,
'#suffix' => '</div>',
) + $base;
// Add prefixes and suffixes.
if (!empty($settings['field']['prefix'])) {
$settings['from']['prefix'] = $settings['field']['prefix'] . $settings['from']['prefix'];
}
if (!empty($settings['field']['suffix'])) {
$settings['to']['suffix'] .= $settings['field']['suffix'];
}
_range_field_widget_form_subelement_prefix_suffix($element, 'from', $settings);
_range_field_widget_form_subelement_prefix_suffix($element, 'to', $settings);
$element['#element_validate'][] = 'range_field_widget_validate';
$element['#attached']['css'][] = drupal_get_path('module', 'range') . '/css/range.admin.css';
return $element;
}
/**
* Helper function. Adds prefix and suffix to a range field widget subelements.
*
* @param array $element
* Range field widget definition array.
* @param string $name
* Form element machine name.
* @param array $settings
* Field instance settings.
*/
function _range_field_widget_form_subelement_prefix_suffix(array &$element, $name, array $settings) {
if (!empty($settings[$name]['prefix'])) {
$prefix = field_filter_xss($settings[$name]['prefix']);
$element[$name]['#field_prefix'] = $prefix;
}
if (!empty($settings[$name]['suffix'])) {
$suffix = field_filter_xss($settings[$name]['suffix']);
$element[$name]['#field_suffix'] = $suffix;
}
}
/**
* FAPI validation of an individual range element.
*/
function range_field_widget_validate($element, &$form_state) {
range_field_widget_validate_subelement('from', $element, $form_state);
range_field_widget_validate_subelement('to', $element, $form_state);
}
/**
* FAPI validation of a FROM or TO range subelement.
*/
function range_field_widget_validate_subelement($subelement, $element, &$form_state) {
$value = $element[$subelement]['#value'];
if ($value === '') {
return;
}
$field = field_widget_field($element, $form_state);
$type = $element['#range_type'];
$valid = TRUE;
if ($type === 'integer') {
$valid = filter_var($value, FILTER_VALIDATE_INT);
$message_args = array(
'%field' => $element[$subelement]['#title'],
);
$message = t('Only numbers are allowed in %field.', $message_args);
}
else {
$options = array(
'options' => array(
'decimal' => $field['settings']['decimal_separator'],
),
);
$valid = filter_var($value, FILTER_VALIDATE_FLOAT, $options);
$message_args = array(
'%field' => $element[$subelement]['#title'],
'@separator' => $field['settings']['decimal_separator'],
);
$message = t('Only numbers and one decimal separator (@separator) allowed in %field.', $message_args);
}
if ($valid === FALSE) {
form_error($element[$subelement], $message);
}
else {
if ($type === 'decimal' || $type === 'float') {
$value = strtr($value, $field['settings']['decimal_separator'], '.');
}
form_set_value($element[$subelement], $value, $form_state);
}
}
/**
* Implements hook_field_widget_error().
*/
function range_field_widget_error($element, $error, $form, &$form_state) {
form_error($element, $error['message']);
}
/**
* Defines properties for range field.
*
* @see entity_metadata_field_entity_property_info()
*/
function range_metadata_field_range_callback(&$info, $entity_type, $field, $instance, $field_type) {
$property =& $info[$entity_type]['bundles'][$instance['bundle']]['properties'][$field['field_name']];
// Define a data structure so it's possible to deal with files and their
// descriptions.
$property['getter callback'] = 'entity_metadata_field_verbatim_get';
$property['setter callback'] = 'entity_metadata_field_verbatim_set';
// Auto-create the field $items as soon as a property is set.
$property['auto creation'] = 'entity_property_create_array';
$property['property info'] = range_property_field_item_range_info($field);
unset($property['query callback']);
}
/**
* Defines info for the properties of the range field data structure.
*/
function range_property_field_item_range_info($field) {
$type = $field['type'] === 'range_integer' ? 'integer' : 'decimal';
$properties['from'] = array(
'type' => $type,
'label' => t('From value'),
'sanitized' => TRUE,
'getter callback' => 'entity_property_verbatim_get',
'setter callback' => 'entity_property_verbatim_set',
'required' => TRUE,
);
$properties['to'] = array(
'type' => $type,
'label' => t('To value'),
'sanitized' => TRUE,
'getter callback' => 'entity_property_verbatim_get',
'setter callback' => 'entity_property_verbatim_set',
'required' => TRUE,
);
return $properties;
}
/**
* Implements hook_views_api().
*/
function range_views_api() {
return array(
'api' => 3,
'path' => drupal_get_path('module', 'range') . '/views',
);
}