View source
<?php
function radioactivity_field_info() {
return array(
RADIOACTIVITY_FIELD_TYPE => array(
'label' => t('Radioactivity'),
'description' => t('This field stores radioactivity in the database.'),
'settings' => array(
'half_life' => 21600,
'decay_granularity' => 60,
'incident_energy' => 10,
'cut_off' => 0.1,
'storage' => 'live',
),
'instance_settings' => array(
'text_processing' => 0,
),
'default_widget' => RADIOACTIVITY_BASIC_WIDGET,
'default_formatter' => RADIOACTIVITY_AJAX_FORMATTER,
),
);
}
function radioactivity_field_settings_form($field, $instance, $has_data) {
$settings = $field['settings'];
$form = array();
if ($field['type'] == RADIOACTIVITY_FIELD_TYPE) {
$form['decay_granularity'] = array(
'#type' => 'textfield',
'#title' => t('Decay granularity'),
'#default_value' => $settings['decay_granularity'],
'#required' => TRUE,
'#description' => t('This setting determines how often at most the radioactivity is decreased by the decay formula. ' . 'The shorter the time, the more accurate the modeling will be, but the more database ' . 'activity is required. The default (1 minute) should be a good starting point.'),
'#element_validate' => array(
'_element_validate_integer_positive',
),
'#disabled' => false,
);
$form['half_life'] = array(
'#type' => 'textfield',
'#title' => t('Half life'),
'#default_value' => $settings['half_life'],
'#required' => TRUE,
'#description' => t('Determines the decay rate of the radioactivity. For exaple, if the decay rate is ' . '3600 (one hour), the radioactivity halves once an hour. If it is now 1000, it will ' . 'be 500 after an hour, 250 after two hours, and so on. The default is 6 hours.'),
'#element_validate' => array(
'_element_validate_integer_positive',
),
'#disabled' => false,
);
$form['incident_energy'] = array(
'#type' => 'textfield',
'#title' => t('View incident energy'),
'#default_value' => $settings['incident_energy'],
'#required' => TRUE,
'#description' => t('Defines the energy emitted by viewing this field.'),
'#element_validate' => array(
'_element_validate_number',
),
'#disabled' => false,
);
$form['cut_off'] = array(
'#type' => 'textfield',
'#title' => t('Energy cut off'),
'#default_value' => $settings['cut_off'],
'#required' => TRUE,
'#description' => t('Defines the energy lever under which the energy is assumed nonexistent.'),
'#element_validate' => array(
'_element_validate_number',
),
);
$form['storage'] = array(
'#type' => 'select',
'#title' => t('Incident storage'),
'#default_value' => $settings['storage'],
'#required' => TRUE,
'#description' => t('Select the storage where all of the incidents are stored before processing them.'),
'#options' => array(
'live' => 'Live storage - write directly to the field database.',
'deferred' => 'Deferred storage - write to a database table for scheduled processing.',
),
);
}
return $form;
}
function radioactivity_field_widget_info() {
return array(
RADIOACTIVITY_BASIC_WIDGET => array(
'label' => t('Basic text field to edit radioactivity'),
'field types' => array(
RADIOACTIVITY_FIELD_TYPE,
),
),
);
}
function radioactivity_field_formatter_info() {
return array(
RADIOACTIVITY_AJAX_FORMATTER => array(
'label' => t('AJAX radioactivity emitter'),
'field types' => array(
RADIOACTIVITY_FIELD_TYPE,
),
),
RADIOACTIVITY_ENERGY_FORMATTER => array(
'label' => t('Textual energy display'),
'field types' => array(
RADIOACTIVITY_FIELD_TYPE,
),
),
RADIOACTIVITY_POPULARITY_FORMATTER => array(
'label' => t('Popularity formatter shows the energy in percentages'),
'field types' => array(
RADIOACTIVITY_FIELD_TYPE,
),
),
);
}
function radioactivity_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$element = array();
switch ($display['type']) {
case RADIOACTIVITY_AJAX_FORMATTER:
$entity_id = 0;
$info = entity_get_info($entity_type);
$id = $info['entity keys']['id'];
$entity_id = $entity->{$id};
if ($entity_id > 0) {
radioactivity_entities($field['id'], $entity_type, $entity_id);
}
break;
case RADIOACTIVITY_ENERGY_FORMATTER:
foreach ($items as $delta => $item) {
$element[$delta] = array(
'#markup' => $item[RADIOACTIVITY_FIELD_ENERGY],
);
}
break;
case RADIOACTIVITY_POPULARITY_FORMATTER:
$maximum = ceil(radioactivity_get_field_maximum($field['id'], $entity_type));
foreach ($items as $delta => $item) {
$energy = $item[RADIOACTIVITY_FIELD_ENERGY];
$energy = $energy > 0 ? $energy : $field_info['settings']['cut_off'];
$element[$delta] = array(
'#markup' => round($energy / $maximum * 100),
);
}
break;
}
return $element;
}
function radioactivity_entities($field_id = NULL, $type = NULL, $entity_id = NULL) {
static $entities = NULL;
if ($entities == NULL) {
$entities = array();
}
if ($entity_id !== NULL) {
$entities[$field_id][$type][] = $entity_id;
}
else {
return $entities;
}
}
function radioactivity_page_alter($page) {
$entities = radioactivity_entities();
if (count($entities) > 0) {
$path = base_path() . variable_get('radioactivity_ajax_callback_path', RADIOACTIVITY_AJAX_PATH);
drupal_add_js(drupal_get_path('module', 'radioactivity') . '/js/radioactivity.js');
drupal_add_js(array(
'radioactivity' => array(
'callback' => $path,
),
), 'setting');
drupal_add_js(array(
'radioactivity' => array(
'entities' => $entities,
),
), 'setting');
}
}
function radioactivity_field_validate($obj_type, $object, $field, $instance, $langcode, &$items, &$errors) {
foreach ($items as $delta => $item) {
if (isset($item[RADIOACTIVITY_FIELD_ENERGY]) < 0) {
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => 'radioactivity_invalid',
'message' => t('Value must be greater than 0'),
);
}
}
}
function radioactivity_field_is_empty($item, $field) {
return strlen($item[RADIOACTIVITY_FIELD_ENERGY]) == 0;
}
function radioactivity_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
if ($field['type'] == RADIOACTIVITY_FIELD_TYPE) {
foreach ($items as $delta => $item) {
$items[$delta][RADIOACTIVITY_FIELD_TIMESTAMP] = time();
}
}
}
function radioactivity_get_field_maximum($field_id, $entity_type) {
static $cache;
if (isset($cache[$field_id . $entity_type])) {
return $cache[$field_id . $entity_type];
}
$field_info = field_info_field_by_id($field_id);
$half_life = $field_info['settings']['half_life'];
$cut_off = $field_info['settings']['cut_off'];
$field_name = $field_info['field_name'];
$table_name = 'field_data_' . $field_name;
$energy = $field_name . '_' . RADIOACTIVITY_FIELD_ENERGY;
$timestamp = $field_name . '_' . RADIOACTIVITY_FIELD_TIMESTAMP;
$query = db_select($table_name, "tb")
->condition("tb.entity_type", $entity_type)
->condition("tb.deleted", "0");
$query
->addExpression("MAX(tb." . $energy . ")", "energy");
$result = $query
->execute()
->fetchField();
if (!$result) {
$result = $cut_off;
}
$cache[$field_id . $entity_type] = $result;
return $cache[$field_id . $entity_type];
}
function radioactivity_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta = 0, $element) {
if (isset($items[$delta]) && $items[$delta][RADIOACTIVITY_FIELD_TIMESTAMP] > 0) {
$seconds = time() - $items[$delta][RADIOACTIVITY_FIELD_TIMESTAMP];
$minutes = floor($seconds / 60);
$hours = floor($minutes / 60);
$seconds = $seconds - $minutes * 60;
$minutes = $minutes - $hours * 60;
$time_ago = t("Radioactivity energy. Last emission @hour hours @min minutes and @sec seconds ago", array(
"@hour" => $hours,
"@min" => $minutes,
"@sec" => $seconds,
));
}
else {
$time_ago = t("Radioactivity energy.");
}
$title = $instance['label'];
$energy = isset($items[$delta][RADIOACTIVITY_FIELD_ENERGY]) ? $items[$delta][RADIOACTIVITY_FIELD_ENERGY] : 0;
$timestamp = isset($items[$delta][RADIOACTIVITY_FIELD_TIMESTAMP]) ? $items[$delta][RADIOACTIVITY_FIELD_TIMESTAMP] : time();
$element += array(
'#type' => 'fieldset',
'#group' => 'Radioactivity',
'#title' => $title,
RADIOACTIVITY_FIELD_ENERGY => array(
'#type' => 'textfield',
'#title' => t("Energy"),
'#default_value' => $energy,
'#description' => $time_ago,
),
RADIOACTIVITY_FIELD_TIMESTAMP => array(
'#type' => 'hidden',
'#title' => t("Last emission"),
'#default_value' => $timestamp,
),
);
return $element;
}