You are here

radioactivity.field.inc in Radioactivity 7

Same filename and directory in other branches
  1. 7.2 radioactivity.field.inc

File

radioactivity.field.inc
View source
<?php

/**
 * Implementation of hook_field_info
 */
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,
    ),
  );
}

/**
 * Implements hook_field_settings_form().
 */
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;
}

/**
 * Implement hook_field_widget_info().
 */
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,
      ),
    ),
  );
}

/**
 * Implements hook_field_formatter_view().
 */
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');
  }
}

/**
 * Implement hook_field_validate().
 */
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'),
      );
    }
  }
}

/**
 * Implement hoo_field_is_empty().
 */
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) {

      // ensure values
      $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);

  // Update field database
  $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;

  // grab update value from deferred values table
  // and update it to the fields table if it is used
  $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];
}

/**
 * Implement hook_field_widget().
 *
 * This widget displayed three text fields\, one each for red, green,
 * and blue. However, the field type defines a single text column,
 * rgb, which needs an HTML color spec. Define an element validate
 * handler that converts our r, g, and b fields into a simulaed single
 * 'rgb' form element.
 */
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.");
  }

  /*
  Do a cool hotness meter and add a nice UI to tweak the value
  for example ... make hotter, make hottest and so on
  Raw energy editing is kind of lame.
  */
  $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;
}