modules/custom/deims_variable/deims_variable.field.inc
<?php
/**
* @file
* Field integration for the DEIMS Variable Field module.
*/
/**
* Implements hook_field_info().
*/
function deims_variable_field_info() {
$info['deims_variable'] = array(
'label' => t('Variable'),
'description' => '',
'default_widget' => 'deims_variable_default',
'default_formatter' => 'deims_variable_default',
);
return $info;
}
/**
* Implements hook_field_load().
*/
function deims_variable_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
foreach ($entities as $id => $entity) {
foreach ($items[$id] as $delta => $item) {
foreach ($item as $column => $value) {
if (!empty($field['columns'][$column]['serialize'])) {
if (empty($value)) {
$items[$id][$delta][$column] = isset($field['columns'][$column]['unserialized default']) ? $field['columns'][$column]['unserialized default'] : NULL;
}
else {
$unserialized_value = @unserialize($value);
if ($unserialized_value !== FALSE || $value == 'b:0;') {
$items[$id][$delta][$column] = $unserialized_value;
}
}
}
}
}
}
}
/**
* Implements hook_field_is_empty().
*/
function deims_variable_field_is_empty($item, $field) {
return empty($item['name'])
&& empty($item['label'])
&& empty($item['definition'])
&& empty($item['missing_values'])
&& empty($item['type'])
&& empty($item['data']['unit'])
&& empty($item['data']['pattern'])
&& empty($item['data']['codes']);
}
/**
* Implements hook_field_validate().
*/
function deims_variable_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
foreach ($items as $delta => $item) {
if (!deims_variable_field_is_empty($item, $field)) {
if (empty($item['name'])) {
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => 'deims_variable_name_empty',
'message' => t('Please provide a <strong>name</strong> for this variable.'),
'element' => array('name'),
);
}
if (empty($item['definition'])) {
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => 'deims_variable_definition_empty',
'message' => t('Please provide a <strong>definition</strong> for this variable.'),
'element' => array('definition'),
);
}
switch ($item['type']) {
case DEIMS_VARIABLE_TYPE_NOMINAL:
// Nominal variables have no detailed options.
break;
case DEIMS_VARIABLE_TYPE_PHYSICAL:
/*if ($item['data']['minimum'] >= $item['data']['maximum']) {
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => 'deims_variable_minimum_error',
'message' => t('%name: the minimum value must be smaller than the maximum value.', array('%name' => $instance['label'])),
);
}
if ($item['data']['maximum'] <= $item['data']['minimum']) {
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => 'deims_variable_maximum_error',
'message' => t('%name: the maximum value must be larger than the minimum value.', array('%name' => $instance['label'])),
);
}*/
break;
case DEIMS_VARIABLE_TYPE_DATE:
break;
case DEIMS_VARIABLE_TYPE_CODES:
if (empty($items[$delta]['data']['codes'])) {
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => 'deims_variable_codes_empty',
'message' => t('Code type variables must not have an empty code list.'),
'element' => array('data', 'codes'),
);
}
break;
}
}
}
}
/**
* Implements hook_field_presave().
*/
function deims_variable_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
foreach ($items as $delta => &$item) {
// Force nominal variables to save an empty missing values array.
if ($item['type'] == DEIMS_VARIABLE_TYPE_NOMINAL) {
$item['missing_values'] = array();
}
if (empty($item['id']) && array_key_exists('id', $item)) {
unset($item['id']);
}
unset($item['field_remove_item']);
// Serialize all columns that are flagged as such in hook_field_schema().
foreach ($item as $column => $value) {
if (!empty($field['columns'][$column]['serialize'])) {
if (!empty($value)) {
$items[$delta][$column] = serialize($value);
}
else {
$items[$delta][$column] = isset($field['columns'][$column]['unserialized default']) ? serialize($field['columns'][$column]['unserialized default']) : NULL;
}
}
}
}
}
/**
* Implements hook_field_widget_info().
*/
function deims_variable_field_widget_info() {
$info['deims_variable_default'] = array(
'label' => t('Default'),
'field types' => array('deims_variable'),
);
return $info;
}
/**
* Implements hook_field_widget_form().
*/
function deims_variable_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
// We need to actually track the form parents of our widget since it may be
// used with inline entity forms.
$field_name = $element['#field_name'];
$langcode = $element['#language'];
$parents = array_merge($element['#field_parents'], array($field_name, $langcode, $delta));
$element['#state_parent'] = $parents[0] . '[' . implode('][', array_slice($parents, 1)) . ']';
$element['#attached']['css'][] = drupal_get_path('module', 'deims_variable') . '/deims_variable.field.css';
$element['#attached']['js'][] = drupal_get_path('module', 'deims_variable') . '/deims_variable.field.js';
if ($field['cardinality'] == 1) {
$element['#type'] = 'fieldset';
}
else {
$details_attributes = array('class' => array('variable-entry'));
if (empty($items[$delta])) {
$details_attributes['open'] = 'open';
}
$element['details_start'] = array(
'#markup' => '<details' . drupal_attributes($details_attributes) . '>',
'#weight' => -200,
);
$element['summary'] = array(
'#markup' => '<summary title="' . t('Click to expand or collapse the variable entry form.') . '">' . t('Unnamed variable') . '</summary>',
'#weight' => -195,
);
$element['details_end'] = array(
'#markup' => '</details>',
'#weight' => 200,
);
}
$element['actions'] = array(
'#type' => 'actions',
// Ensure that the actions element is output inbetween the <details> and
// the <summary> elements.
'#weight' => -205,
'#access' => $field['cardinality'] == FIELD_CARDINALITY_UNLIMITED,
);
$element['id'] = array(
'#type' => 'value',
'#value' => isset($items[$delta]['id']) ? $items[$delta]['id'] : NULL,
);
$element['name'] = array(
'#prefix' => '<div class="variable-left-column form-wrapper">',
'#type' => 'textfield',
'#title' => t('Name'),
'#description' => t('The name of the actual column in the source file.'),
'#default_value' => isset($items[$delta]['name']) ? $items[$delta]['name'] : '',
'#required' => $instance['required'],
'#maxlength' => 255,
'#size' => 30,
'#attributes' => array('class' => array('variable-name')),
);
$element['label'] = array(
'#type' => 'textfield',
'#title' => t('Label'),
'#description' => t('The human-readable label of the variable.'),
'#default_value' => isset($items[$delta]['label']) ? $items[$delta]['label'] : '',
'#maxlength' => 255,
'#attributes' => array('class' => array('variable-label')),
);
$element['definition'] = array(
'#type' => 'textarea',
'#title' => t('Definition'),
'#description' => t('The definition of the variable (column). Example: The air temperature collected at 2 meters above the ground. Other example: The set of codes used to categorize the sub-plots where the census studies were conducted.'),
'#default_value' => isset($items[$delta]['definition']) ? $items[$delta]['definition'] : '',
'#required' => $instance['required'],
'#rows' => 2,
);
$element['missing_values'] = array(
'#type' => 'textarea',
'#title' => t('Missing values'),
'#description' => t("Any missing value codes should be described here. Use a pipe character to separate the code from the explanation of the code used for the missing value. For example: -9999|Instrument Failed, NA|Not Applies, -77777|Out of calibration Range, BLANK|Not sure, but no good."),
'#default_value' => isset($items[$delta]['missing_values']) ? list_allowed_values_string($items[$delta]['missing_values']) : '',
'#placeholder' => "-9999|Instrument Failed",
'#rows' => 2,
'#element_validate' => array('list_allowed_values_setting_validate'),
'#field_has_data' => FALSE,
'#field' => array('type' => 'list_text'),
'#suffix' => '</div><div class="variable-right-column">',
'#states' => array(
'invisible' => array(
// Nominal variables do not have missing values, so hide this field.
':input[name="' . $element['#state_parent'] . '[type]"]' => array('value' => DEIMS_VARIABLE_TYPE_NOMINAL),
),
),
'#attributes' => array('class' => array('variable-missing-values')),
);
if ($field['cardinality'] == FIELD_CARDINALITY_UNLIMITED) {
$element['actions']['remove_button'] = array(
'#type' => 'submit',
'#value' => t('Remove'),
'#name' => implode('_', $parents) . '_remove_button',
'#delta' => $delta,
'#submit' => array('deims_variable_remove_submit'),
'#limit_validation_errors' => array(),
'#ajax' => array(
'path' => 'deims-variable/field-remove-item/ajax',
'effect' => 'fade',
),
'#attributes' => array(
'class' => array('remove-button'),
),
);
}
// Set up a trackable target ID so the ajax system knows what content to
// replace.
$target_id = 'edit-' . drupal_clean_css_identifier(implode('-', $parents)) . '-data-values';
$element['type'] = array(
'#type' => 'select',
'#title' => t('Type'),
'#description' => t('What type of variable is this?'),
'#options' => _deims_variable_types(),
'#default_value' => isset($items[$delta]['type']) ? $items[$delta]['type'] : DEIMS_VARIABLE_TYPE_NOMINAL,
'#ajax' => array(
'wrapper' => $target_id,
'callback' => 'deims_variable_variable_type_select_callback',
),
'#attributes' => array('class' => array('variable-type')),
);
$element['data'] = array(
'#type' => 'container',
'#tree' => TRUE,
'#weight' => 50,
'#prefix' => '<div id="' . $target_id . '">',
'#suffix' => '</div></div>',
);
// Check if the type value has been submitted.
$type_exists = FALSE;
$type = drupal_array_get_nested_value($form_state, array_merge(array('values'), $parents, array('type')), $type_exists);
if (!$type_exists && !empty($element['type']['#default_value'])) {
$type = $element['type']['#default_value'];
}
switch ($type) {
case DEIMS_VARIABLE_TYPE_NOMINAL:
// Nominal variables have no detailed options.
break;
case DEIMS_VARIABLE_TYPE_PHYSICAL:
$element['data']['unit'] = array(
'#type' => 'select_or_other',
'#title' => t('Unit of measure'),
'#description' => t('The unit reference to quantify a measurement. Usually these are well know standard units with reference to one of the many reference systems (metric systems) such as the centimeter-gram-second (cgs) or the international system (SI), or the units typically used in the US (inch, mile, pound, gallon, etc).'),
// Use NULL as a default value here instead of an empty string, to
// prevent 'Illegal choice' errors if this element is converted to a
// select_or_other type below.
'#default_value' => isset($items[$delta]['data']['unit']) ? $items[$delta]['data']['unit'] : NULL,
'#options' => LterUnitHelper::getUnitOptions(1),
'#required' => TRUE,
'#attributes' => array(
'data-create_option_text' => t('Use other unit'),
),
'#chosen' => TRUE,
);
$element['data']['maximum'] = array(
'#type' => 'numberfield',
'#title' => t('Maximum value'),
'#description' => t('The maximum value attainable by this variable or measurement.'),
'#default_value' => isset($items[$delta]['data']['maximum']) ? $items[$delta]['data']['maximum'] : '',
'#size' => 5,
'#step' => 'any',
);
$element['data']['minimum'] = array(
'#type' => 'numberfield',
'#title' => t('Minimum value'),
'#description' => t('The mininum value attainable by this variable or measurement.'),
'#default_value' => isset($items[$delta]['data']['minimum']) ? $items[$delta]['data']['minimum'] : '',
'#size' => 5,
'#step' => 'any',
);
$element['data']['precision'] = array(
'#type' => 'numberfield',
'#title' => t('Precision'),
'#description' => t('The precision value of this variable or measurement.'),
'#default_value' => isset($items[$delta]['data']['precision']) ? $items[$delta]['data']['precision'] : '',
'#size' => 5,
'#step' => 'any',
);
break;
case DEIMS_VARIABLE_TYPE_DATE:
$element['data']['pattern'] = array(
'#type' => 'textfield',
'#title' => t('Date and/or time pattern'),
'#description' => t('This is the format in which the date is expressed.'),
'#default_value' => isset($items[$delta]['data']['pattern']) ? $items[$delta]['data']['pattern'] : '',
'#required' => TRUE,
'#size' => 30,
'#placeholder' => 'DD/MM/YYYY',
);
break;
case DEIMS_VARIABLE_TYPE_CODES:
$element['data']['codes'] = array(
'#type' => 'textarea',
'#title' => t('Codes'),
'#description' => t('The possible codes this variable can contain. Enter one code per line, in the format code|label. The label is optional: if a line contains a single string, it will be used as both code and label.'),
'#default_value' => isset($items[$delta]['data']['codes']) ? list_allowed_values_string($items[$delta]['data']['codes']) : '',
'#required' => TRUE,
'#placeholder' => "L|Larvae",
'#rows' => 9,
'#element_validate' => array('list_allowed_values_setting_validate'),
'#field_has_data' => FALSE,
'#field' => array('type' => 'list_text'),
'#attributes' => array('class' => array('variable-data-codes')),
);
break;
}
return $element;
}
function deims_variable_variable_type_select_callback($form, $form_state) {
$parents = $form_state['triggering_element']['#array_parents'];
// The type element triggered this, so remove it from parents.
array_pop($parents);
// We want the data part of the form.
$parents[] = 'data';
return drupal_array_get_nested_value($form, $parents);
}
/**
* Page callback to handle AJAX for removing a field collection item.
*
* Copied from field_collection_remove_js().
*
* This is a direct page callback. The actual job of deleting the item is
* done in the submit handler for the button, so all we really need to
* do is process the form and then generate output. We generate this
* output by doing a replace command on the id of the entire form element.
*/
function deims_variable_remove_js() {
require_once DRUPAL_ROOT . '/includes/form.inc';
// drupal_html_id() very helpfully ensures that all html IDS are unique
// on a page. Unfortunately what it doesn't realize is that the IDs
// we are generating are going to replace IDs that already exist, so
// this actually works against us.
if (isset($_POST['ajax_html_ids'])) {
unset($_POST['ajax_html_ids']);
}
list($form, $form_state) = ajax_get_form();
drupal_process_form($form['#form_id'], $form, $form_state);
// Get the information on what we're removing.
$button = $form_state['triggering_element'];
// Go two levels up in the form, to the whole widget.
$element = drupal_array_get_nested_value($form, array_slice($button['#array_parents'], 0, -4));
// Now send back the proper AJAX command to replace it.
$return = array(
'#type' => 'ajax',
'#commands' => array(
ajax_command_replace('#' . $element['#id'], drupal_render($element))
),
);
// Because we're doing this ourselves, messages aren't automatic. We have
// to add them.
$messages = theme('status_messages');
if ($messages) {
$return['#commands'][] = ajax_command_prepend('#' . $element['#id'], $messages);
}
return $return;
}
/**
* Submit callback to remove an item from the field UI multiple wrapper.
*
* Copied from field_collection_remove_submit()
*
* When a remove button is submitted, we need to find the item that it
* referenced and delete it. Since field UI has the deltas as a straight
* unbroken array key, we have to renumber everything down. Since we do this
* we *also* need to move all the deltas around in the $form_state['values']
* and $form_state['input'] so that user changed values follow. This is a bit
* of a complicated process.
*/
function deims_variable_remove_submit($form, &$form_state) {
$button = $form_state['triggering_element'];
$delta = $button['#delta'];
// Where in the form we'll find the parent element.
$address = array_slice($button['#array_parents'], 0, -3);
// Go one level up in the form, to the widgets container.
$parent_element = drupal_array_get_nested_value($form, $address);
$field_name = $parent_element['#field_name'];
$langcode = $parent_element['#language'];
$parents = $parent_element['#field_parents'];
$field_state = field_form_get_state($parents, $field_name, $langcode, $form_state);
// Go ahead and renumber everything from our delta to the last
// item down one. This will overwrite the item being removed.
for ($i = $delta; $i <= $field_state['items_count']; $i++) {
$old_element_address = array_merge($address, array($i + 1));
$new_element_address = array_merge($address, array($i));
$moving_element = drupal_array_get_nested_value($form, $old_element_address);
$moving_element_value = drupal_array_get_nested_value($form_state['values'], $old_element_address);
$moving_element_input = drupal_array_get_nested_value($form_state['input'], $old_element_address);
// Tell the element where it's being moved to.
$moving_element['#parents'] = $new_element_address;
// Move the element around.
form_set_value($moving_element, $moving_element_value, $form_state);
drupal_array_set_nested_value($form_state['input'], $moving_element['#parents'], $moving_element_input);
}
// Then remove the last item. But we must not go negative.
if ($field_state['items_count'] > 0) {
$field_state['items_count']--;
}
// Fix the weights. Field UI lets the weights be in a range of
// (-1 * item_count) to (item_count). This means that when we remove one,
// the range shrinks; weights outside of that range then get set to
// the first item in the select by the browser, floating them to the top.
// We use a brute force method because we lost weights on both ends
// and if the user has moved things around, we have to cascade because
// if I have items weight weights 3 and 4, and I change 4 to 3 but leave
// the 3, the order of the two 3s now is undefined and may not match what
// the user had selected.
$input = drupal_array_get_nested_value($form_state['input'], $address);
// Sort by weight
uasort($input, '_field_sort_items_helper');
// Reweight everything in the correct order.
$weight = -1 * $field_state['items_count'];
foreach ($input as $key => $item) {
if ($item) {
$input[$key]['_weight'] = $weight++;
}
}
drupal_array_set_nested_value($form_state['input'], $address, $input);
field_form_set_state($parents, $field_name, $langcode, $form_state, $field_state);
$form_state['rebuild'] = TRUE;
}
/**
* Implements hook_field_widget_error().
*/
function deims_variable_field_widget_error($element, $error, $form, &$form_state) {
$error_element = $element;
if (!empty($error['element'])) {
$error_element = drupal_array_get_nested_value($element, $error['element']);
}
if ($error_element) {
form_error($error_element, $error['message']);
}
}
/**
* Implements hook_field_formatter_info().
*/
function deims_variable_field_formatter_info() {
$info['deims_variable_summary'] = array(
'label' => t('Summary with details'),
'field types' => array('deims_variable'),
);
$info['deims_variable_table'] = array(
'label' => t('Table'),
'field types' => array('deims_variable'),
);
$info['eml_attribute_list'] = array(
'label' => t('EML attributeList'),
'field types' => array('deims_variable'),
);
$info['bdp_attribute_list'] = array(
'label' => t('BDP attributeList'),
'field types' => array('deims_variable'),
);
$info['iso_attribute_list'] = array(
'label' => t('ISO attributeList'),
'field types' => array('deims_variable'),
);
return $info;
}
/**
* Implements hook_field_formatter_view().
*/
function deims_variable_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$element = array();
switch ($display['type']) {
case 'deims_variable_summary':
foreach ($items as $delta => $item) {
$element[$delta] = array(
'#theme' => 'deims_variable_summary',
'#variable' => $item,
);
}
break;
case 'deims_variable_table':
if (!empty($items)) {
// Display all values in a single element.
$element[0] = array(
'#theme' => 'deims_variable_table',
'#variables' => $items,
);
}
break;
case 'eml_attribute_list':
$attributes = array();
foreach ($items as $delta => $item) {
$attribute = array();
$attribute['attributeName'] = $item['name'];
$attribute['attributeLabel'] = !empty($item['label']) ? $item['label'] : $item['name'];
$attribute['attributeDefinition'] = $item['definition'];
switch ($item['type']) {
case DEIMS_VARIABLE_TYPE_NOMINAL:
$attribute['storageType'] = 'string';
$attribute['measurementScale']['nominal'] = array();
$attribute['measurementScale']['nominal']['nonNumericDomain'] = array();
$attribute['measurementScale']['nominal']['nonNumericDomain']['textDomain']['definition'] = $item['definition'];
break;
case DEIMS_VARIABLE_TYPE_PHYSICAL:
$attribute['measurementScale']['ratio'] = array();
$attribute['measurementScale']['ratio']['unit'] = array();
if (LterUnitHelper::isUnitStandard($item['data']['unit'])) {
$attribute['measurementScale']['ratio']['unit']['standardUnit'] = $item['data']['unit'];
}
else {
$attribute['measurementScale']['ratio']['unit']['customUnit'] = $item['data']['unit'];
}
if (drupal_strlen($item['data']['precision'])) {
$attribute['measurementScale']['ratio']['precision'] = $item['data']['precision'];
}
$attribute['measurementScale']['ratio']['numericDomain'] = array();
$attribute['measurementScale']['ratio']['numericDomain']['numberType'] = 'real';
if (drupal_strlen($item['data']['minimum'])) {
$attribute['measurementScale']['ratio']['numericDomain']['bounds'][] = array(
'key' => 'minimum',
'attributes' => array('exclusive' => 'false'),
'value' => $item['data']['minimum'],
);
}
if (drupal_strlen($item['data']['maximum'])) {
$attribute['measurementScale']['ratio']['numericDomain']['bounds'][] = array(
'key' => 'maximum',
'attributes' => array('exclusive' => 'false'),
'value' => $item['data']['maximum'],
);
}
break;
case DEIMS_VARIABLE_TYPE_DATE:
$attribute['storageType'] = 'date';
$attribute['measurementScale']['dateTime'] = array();
$attribute['measurementScale']['dateTime']['formatString'] = $item['data']['pattern'];
break;
case DEIMS_VARIABLE_TYPE_CODES:
$attribute['storageType'] = 'string';
$attribute['measurementScale']['nominal'] = array();
$attribute['measurementScale']['nominal']['nonNumericDomain'] = array();
$attribute['measurementScale']['nominal']['nonNumericDomain']['enumeratedDomain'] = array();
foreach ($item['data']['codes'] as $key => $value) {
$attribute['measurementScale']['nominal']['nonNumericDomain']['enumeratedDomain'][] = array(
'key' => 'codeDefinition',
'value' => array(
'code' => $key,
'definition' => $value,
),
);
}
break;
}
foreach ($item['missing_values'] as $key => $value) {
$attribute[] = array(
'key' => 'missingValueCode',
'value' => array(
'code' => $key,
'codeExplanation' => $value,
),
);
}
$attributes[] = array(
'key' => 'attribute',
'value' => $attribute,
);
}
if (!empty($attributes)) {
$element = array(
'#theme' => 'eml_elements',
'#eml' => $attributes,
);
}
break;
case 'bdp_attribute_list':
$attributes = array();
foreach ($items as $delta => $item) {
$attribute = array();
$attribute['attrlabl'] = !empty($item['label']) ? $item['label'] : $item['name'];
$attribute['attrdef'] = $item['definition'];
$attribute['attrdefs'] = 'The data provider';
switch ($item['type']) {
case DEIMS_VARIABLE_TYPE_NOMINAL:
$attribute['attrdomv']['udom'] = $item['definition'];
break;
case DEIMS_VARIABLE_TYPE_PHYSICAL:
$attribute['attrdomv']['rdom'] = array();
if (drupal_strlen($item['data']['minimum'])) {
$attribute['attrdomv']['rdom']['rdommin']= $item['data']['minimum'];
}
if (drupal_strlen($item['data']['maximum'])) {
$attribute['attrdomv']['rdom']['rdommax'] = $item['data']['maximum'];
}
$attribute['attrdomv']['rdom']['attrunit'] = $item['data']['unit'];
if (drupal_strlen($item['data']['precision'])) {
$attribute['attrdomv']['rdom']['attrmres'] = $item['data']['precision'];
}
break;
case DEIMS_VARIABLE_TYPE_DATE:
$attribute['attrdomv']['edom'] = array();
$attribute['attrdomv']['edom']['edomv'] = 'calendar date/time';
$attribute['attrdomv']['edom']['edomvd'] = $item['data']['pattern'];
$attribute['attrdomv']['edom']['edomvds'] = 'gregorian calendar';
break;
case DEIMS_VARIABLE_TYPE_CODES:
$attribute['attrdomv'] = array();
foreach ($item['data']['codes'] as $key => $value) {
$attribute['attrdomv'][] = array(
'key' => 'edom',
'value' => array(
'edomv' => $key,
'edomvd' => $value,
'edomvds' => 'The data provider',
),
);
}
break;
}
$attributes[] = array(
'key' => 'attr',
'value' => $attribute,
);
}
if (!empty($attributes)) {
$element = array(
'#theme' => 'bdp_elements',
'#bdp' => $attributes,
);
}
break;
case 'iso_attribute_list':
// ISO 19110 is not yet part of ISO19115, it is in the DIS stage (Draft)
$attributes = array();
foreach ($items as $delta => $item) {
$attribute = array();
$attribute['gfc:FC_FeatureAttribute'] = array();
$attribute['gfc:FC_FeatureAttribute']['gfc:memberName'] = array();
$attribute['gfc:FC_FeatureAttribute']['gfc:memberName']['gco:LocalName'] = $item['name'];
$attribute['gfc:FC_FeatureAttribute']['gfc:definition']['gco:CharacterString'] = $item['definition'];
$attribute['gfc:FC_FeatureAttribute']['gfc:cardinality']['gco:Multiplicity gco:nilreason=unknown']='';
switch ($item['type']) {
case DEIMS_VARIABLE_TYPE_PHYSICAL:
$unitmetadata = array();
if (drupal_strlen($item['data']['precision'])) {
$unitmetadata['precision'] = $item['data']['precision'];
}
if (drupal_strlen($item['data']['minimum'])) {
$unitmetatada['minimum'] = $item['data']['minimum'];
}
if (drupal_strlen($item['data']['maximum'])) {
$unitmetadata['maximum'] = $item['data']['maximum'];
}
$unitname = "gml:unitDefinition gml:id=" . $item['data']['unit'];
$attribute['gfc:FC_FeatureAttribute']['gfc:valueMeasurementUnit'] = array();
$attribute['gfc:FC_FeatureAttribute']['gfc:valueMeasurementUnit'][$unitname] = array();
if( !$unitmetadata) {
$attribute['gfc:FC_FeatureAttribute']['gfc:valueMeasurementUnit'][$unitname]['gml:metadataProperty']['GenericMetadata'] = $unitmetadata;
}
$attribute['gfc:FC_FeatureAttribute']['gfc:valueMeasurementUnit'][$unitname]['gml:identifier codeSpace=http://unit.lternet.edu']='';
break;
case DEIMS_VARIABLE_TYPE_DATE:
$attribute['gfc:FC_FeatureAttribute']['gfc:code']['gco:CharacterString'] = 'Date Time Format: '. $item['data']['pattern'];
break;
case DEIMS_VARIABLE_TYPE_CODES:
foreach ($item['data']['codes'] as $key => $value) {
$attribute['gfc:FC_FeatureAttribute'][] = array(
'key' => 'gfc:listedValue',
'value' => array(
'gfc:FC_ListedValue' => array(
'gfc:label' => array('gco:CharacterString' => $key),
'gfc:definition' => array('gco:CharacterString' => $value),
),
),
);
}
break;
}
$attributes[] = array(
'key' => 'gfc:carrierOfCharacteristics',
'value' => $attribute,
);
}
if (!empty($attributes)) {
$element = array(
'#theme' => 'iso_elements',
'#iso' => $attributes,
);
}
break;
}
return $element;
}
/**
* Implements hook_field_widget_WIDGET_TYPE_form_alter() on behalf of options_element module.
*/
function options_element_field_widget_deims_variable_default_form_alter(&$element, &$form_state, $context) {
// @todo What's the intention of usage here?
$items = $context['items'];
$delta = $context['delta'];
deims_variable_convert_select_to_options_element($element['missing_values']);
if (isset($element['data']['codes'])) {
deims_variable_convert_select_to_options_element($element['data']['codes']);
}
}
function deims_variable_convert_select_to_options_element(array &$element) {
$options = list_extract_allowed_values($element['#default_value'], array('type' => 'list_text'), FALSE);
$element['#type'] = 'options';
$element['#key_type'] = 'custom';
$element['#key_type_toggled'] = TRUE;
$element['#options'] = !empty($options) ? $options : array();
$element['#default_value_allowed'] = FALSE;
$element['#element_validate'] = array_merge(element_info_property('options', '#element_validate'), array('deims_variable_convert_options_value_to_array'));
}
function deims_variable_convert_options_value_to_array($element, &$form_state) {
form_set_value($element, $element['#value']['options'], $form_state);
}