units_field.module in Units of Measurement 7.2
Provide field type for storing measured values.
File
units_field/units_field.moduleView source
<?php
/**
* @file
* Provide field type for storing measured values.
*/
/**
* Implements hook_field_info().
*/
function units_field_field_info() {
return array(
'units_value' => array(
'label' => t('Measured value'),
'description' => t('Store measured quantities in this field and them seamlessly execute units conversion.'),
'settings' => array(
'dimension' => array(
'type' => 'measure',
'mathematical_expression' => NULL,
'measure' => NULL,
),
),
'instance_settings' => array(),
'default_widget' => 'units_value_expression',
'default_formatter' => 'units_value_expression',
),
);
}
/**
* Implements hook_field_settings_form().
*/
function units_field_field_settings_form($field, $instance, $has_data) {
$form = array();
switch ($field['type']) {
case 'units_value':
$form['dimension'] = array(
'#tree' => TRUE,
);
$form['dimension']['type'] = array(
'#type' => 'radios',
'#title' => t('Format to specify dimension of this field'),
'#options' => array(
'measure' => t('By selecting a measure'),
'mathematical_expression' => t('By entering mathematical expression'),
),
'#default_value' => $field['settings']['dimension']['type'],
'#disabled' => $has_data,
);
$mathematical_expression = units_mathematical_expression_create_from_postfix($field['settings']['dimension']['mathematical_expression']);
$form['dimension']['mathematical_expression'] = array(
'#type' => 'units_mathematical_expression',
'#title' => t('Mathematical expression'),
'#description' => t('Specify here mathematical expression that defines dimension of this field.'),
'#default_value' => $mathematical_expression,
'#value_format' => 'postfix',
'#states' => array(
'visible' => array(
':radio[name$="[dimension][type]"]' => array(
'value' => 'mathematical_expression',
),
),
),
'#disabled' => $has_data,
);
$options = array();
foreach (units_measure_load_multiple() as $measure) {
$options[$measure
->identifier()] = entity_label($measure
->entityType(), $measure);
}
$form['dimension']['measure'] = array(
'#type' => 'radios',
'#title' => t('Select underlying measure for this field'),
'#options' => $options,
'#default_value' => isset($field['settings']['dimension']['measure']) ? $field['settings']['dimension']['measure'] : NULL,
'#disabled' => $has_data,
'#states' => array(
'visible' => array(
':radio[name$="[dimension][type]"]' => array(
'value' => 'measure',
),
),
),
);
break;
}
return $form;
}
/**
* Implements hook_field_widget_info().
*/
function units_field_field_widget_info() {
return array(
'units_value_expression' => array(
'label' => t('Mathematical expression'),
'description' => t('Specify value through mathematical formula'),
'field types' => array(
'units_value',
),
'settings' => array(
'expression_postfix' => NULL,
),
),
);
}
/**
* Implements hook_field_formatter_info().
*/
function units_field_field_formatter_info() {
return array(
'units_value_expression' => array(
'label' => t('Mathematical expression'),
'description' => t('Format value as mathematical expression'),
'field types' => array(
'units_value',
),
'settings' => array(
'expression_postfix' => NULL,
),
),
);
}
/**
* Implements hook_field_is_empty().
*/
function units_field_field_is_empty($item, $field) {
switch ($field['type']) {
case 'units_value':
return !isset($item['expression']);
break;
}
}
/**
* Implements hook_field_presave().
*/
function units_field_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
foreach ($items as &$item) {
$item['expression']
->save();
$item['mathematical_expression_id'] = $item['expression']
->getMathematicalExpressionId();
}
}
/**
* Implements hook_field_load().
*/
function units_field_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
// TODO: this should be replaced with a batch load in a single SQL SELECT.
foreach ($entities as $id => $entity) {
foreach ($items[$id] as $delta => $item) {
$items[$id][$delta]['expression'] = units_mathematical_expression_load($item['mathematical_expression_id']);
}
}
}
/**
* Implements hook_field_delete().
*/
function units_field_field_delete($entity_type, $entity, $field, $instance, $langcode, &$items) {
// TODO: this should be replaced with a batch delete in a single SQL DELETE.
foreach ($items as $item) {
units_mathematical_expression_delete($item['mathematical_expression_id']);
}
}
/**
* Implements hook_field_delete_revision().
*/
function units_field_field_delete_revision($entity_type, $entity, $field, $instance, $langcode, &$items) {
// TODO: this should be replaced with a batch delete in a single SQL DELETE.
foreach ($items as $item) {
units_mathematical_expression_delete($item['mathematical_expression_id']);
}
}
/**
* Implements hook_field_validate().
*/
function units_field_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
foreach ($items as $delta => $item) {
try {
if ($item['expression']) {
$item['expression']
->getExpression()
->evaluate();
}
} catch (UnitsMathematicalExpressionDimensionException $e) {
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => 'units_mathematical_expression_dimension_inconsistency',
'message' => t('%name: the mathematical expression contains dimension inconsistency. Details: @exception', array(
'%name' => $instance['label'],
'@exception' => $e
->getMessage(),
)),
);
} catch (UnitsMathematicalExpressionMalformedException $e) {
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => 'units_mathematical_expression_malformed',
'message' => t('%name: the mathematical expression is malformed. Details: @exception', array(
'%name' => $instance['label'],
'@exception' => $e
->getMessage(),
)),
);
}
}
}
/**
* Implements hook_field_widget_form().
*/
function units_field_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
switch ($instance['widget']['type']) {
case 'units_value_expression':
$element['expression'] = array(
'#type' => 'units_mathematical_expression',
'#title' => $instance['label'],
'#required' => $element['#required'],
'#value_format' => 'object',
'#default_value' => isset($items[$delta]['expression']) ? $items[$delta]['expression'] : NULL,
'#allowed_dimension' => units_field_dimension($field),
);
break;
}
return $element;
}
/**
* Implements hook_field_formatter_settings_form().
*/
function units_field_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
$display = $instance['display'][$view_mode];
$settings = $display['settings'];
$element = array();
switch ($display['type']) {
case 'units_value_expression':
$mathematical_expression = NULL;
if (isset($settings['expression_postfix'])) {
$mathematical_expression = units_mathematical_expression_create_from_postfix($settings['expression_postfix']);
}
$element['expression_postfix'] = array(
'#type' => 'units_mathematical_expression',
'#title' => t('Output as the following'),
'#value_format' => 'postfix',
'#default_value' => $mathematical_expression,
'#description' => t('Specify here mathematical expression. All constant members of this mathematical expression will be replaced by real values from the field data. Leave empty to output in original format.'),
'#allowed_dimension' => units_field_dimension($field),
);
break;
}
return $element;
}
/**
* Implements hook_field_formatter_settings_summary().
*/
function units_field_field_formatter_settings_summary($field, $instance, $view_mode) {
$display = $instance['display'][$view_mode];
$summary = '';
switch ($display['type']) {
case 'units_value_expression':
$mathematical_expression = units_field_display_mathematical_expression($display);
$summary = $mathematical_expression ? check_plain($mathematical_expression
->getExpression()
->toInfix()) : t('Original');
break;
}
return $summary;
}
/**
* Implements hook_field_formatter_view().
*/
function units_field_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$element = array();
switch ($display['type']) {
case 'units_value_expression':
foreach ($items as $delta => $item) {
$output_mathematical_expression = units_field_display_mathematical_expression($display);
if (is_object($output_mathematical_expression)) {
$output_mathematical_expression = $output_mathematical_expression
->getExpression();
units_mathematical_expression_format_as($item['expression']
->getExpression(), $output_mathematical_expression);
}
else {
// Since no output format was given, we output it in original
// mathematical expression.
$output_mathematical_expression = $item['expression']
->getExpression();
}
$element[$delta] = array(
'#markup' => check_plain($output_mathematical_expression
->toInfix()),
);
}
break;
}
return $element;
}
/**
* Retrieve allowed dimension for a provided field.
*
* @param array $field
* Field definition array for which to determine allowed dimension
*
* @return array
* Dimension array that is allowed in the provided field
*/
function units_field_dimension($field) {
$mathematical_expression = NULL;
switch ($field['settings']['dimension']['type']) {
case 'mathematical_expression':
$mathematical_expression = units_mathematical_expression_create_from_postfix($field['settings']['dimension']['mathematical_expression'])
->getExpression();
break;
case 'measure':
$efq = new EntityFieldQuery();
$efq
->entityCondition('entity_type', 'units_unit');
$efq
->entityCondition('bundle', $field['settings']['dimension']['measure']);
$efq
->range(0, 1);
$result = $efq
->execute();
$result = array_keys($result['units_unit']);
$mathematical_expression = units_unit_load(reset($result));
break;
}
return $mathematical_expression
->dimension();
}
/**
* Fetch expected output format from the provided display.
*
* @param array $display
* Display whose expected output format should be fetched
*
* @return UnitsMathematicalExpressionWrapper
* Expected output format from the provided display in the form of
* mathematical expression object. If none is defined in the provided display,
* NULL is returned
*/
function units_field_display_mathematical_expression($display) {
// We replace all constants with 1, to make sure quantity can be distributed
// properly.
$expression_postfix = $display['settings']['expression_postfix'];
$expression_postfix = preg_replace('#\\b\\d+\\b#', 1, $expression_postfix);
return units_mathematical_expression_create_from_postfix($expression_postfix);
}