You are here

radioactivity.module in Radioactivity 7

File

radioactivity.module
View source
<?php

define("RADIOACTIVITY_UI_PATH", "admin/structure/radioactivity");
define("RADIOACTIVITY_AJAX_PATH", "radioactivity_ajax.php");

/* field API definitions */
define("RADIOACTIVITY_FIELD_TYPE", "radioactivity");
define("RADIOACTIVITY_FIELD_ENERGY", "radioactivity_energy");
define("RADIOACTIVITY_FIELD_TIMESTAMP", "radioactivity_timestamp");
define("RADIOACTIVITY_AJAX_FORMATTER", "radioactivity_ajax_formatter");
define("RADIOACTIVITY_ENERGY_FORMATTER", "radioactivity_energy_formatter");
define("RADIOACTIVITY_POPULARITY_FORMATTER", "radioactivity_popularity_formatter");
define("RADIOACTIVITY_BASIC_WIDGET", "radioactivity_basic_widget");
require_once 'radioactivity.field.inc';

/**
 * Implementation of hook_permission
 */
function radioactivity_permission() {
  return array(
    'administer radioactivity' => array(
      'title' => t('Administer radioactivity'),
      'description' => t('Manage Radioactivity settings and profiles.'),
    ),
  );
}

/**
 * Implementation of hook help
 */
function radioactivity_help($path, $arg) {
  $output = '';
  switch ($path) {
    case "admin/help#radioactivity":
      $output = '<p>' . t('This module is the core for all radioactivity functionality.') . '</p>';
      break;
  }
  return $output;
}

/**
 * Implementation of hook_menu
 */
function radioactivity_menu() {
  $items = array();
  $items[RADIOACTIVITY_UI_PATH] = array(
    'title' => 'Radioactivity',
    'description' => 'Configure settings for radioactivity.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'radioactivity_admin_general_form',
    ),
    'access arguments' => array(
      'administer radioactivity',
    ),
    'type' => MENU_NORMAL_ITEM,
    'file' => 'radioactivity-admin-ui.inc',
  );

  // Bind the path given in the R settings to the callback
  $path = variable_get("radioactivity_ajax_callback_path", RADIOACTIVITY_AJAX_PATH);
  $items[$path] = array(
    'page callback' => 'radioactivity_ajax_callback',
    'type' => MENU_CALLBACK,
    'access arguments' => array(
      'access content',
    ),
  );
  return $items;
}

/**
 * Page ajax callback
 */
function radioactivity_ajax_callback() {
  $data = $_REQUEST['entities'];
  $time_now = time();
  if (is_array($data)) {
    foreach ($data as $field_id => $entities) {
      radioactivity_incident_emit($field_id, $entities);
    }
  }

  // @TODO: needs a workaround as this will cause major slowdowns at some point
  field_cache_clear();
}

/**
 *
 * Enter description here ...
 * @param unknown_type $field_id
 */
function radiactivity_get_incident_storage($field_id) {
  static $cache = array();

  // for instances
  static $included = false;

  // for base class
  static $includes = array();

  // for other classes
  $field_info = field_info_field_by_id($field_id);
  $storage = $field_info['settings']['storage'];
  $key = $storage . '-' . $field_id;

  // make hookable
  // if cached?
  if (isset($cache[$key])) {
    return $cache[$key];
  }
  $class = "radioactivity_" . $storage . "_incident_storage";

  // main class included?
  if (!$included) {
    include "storage/radioactivity_incident_storage.php";
    $included = true;
  }

  // this storage class included?
  if (!isset($includes[$storage])) {
    include "storage/" . $class . ".php";
    $includes[$storage] = true;
  }

  // add to cache
  if (class_exists($class)) {
    $cache[$key] = new $class($field_id);
  }
  else {
    $cache[$key] = NULL;
  }
  return $cache[$key];
}

/**
 * Emit the indicental energy of the field
 * @param field ID $field_id
 * @param entity ID $entity_id
 */
function radioactivity_incident_emit($field_id, $entities) {
  $storage = radiactivity_get_incident_storage($field_id);
  if ($storage) {
    $storage
      ->add_incident($entities);
  }
  else {
    print "No storage";
  }
}

/**
 * Implementation of hook_cron
 */
function radioactivity_cron() {
  $fields = db_select("field_config", "fc")
    ->fields("fc", array(
    "id",
  ))
    ->condition("fc.type", RADIOACTIVITY_FIELD_TYPE)
    ->condition("fc.deleted", "0")
    ->execute();
  $time_now = time();

  // @TODO: add deferred processing
  while ($row = $fields
    ->fetchObject()) {
    $field_info = field_info_field_by_id($row->id);
    $storage = radiactivity_get_incident_storage($row->id);

    // Process incidents
    $storage
      ->process_incidents();

    // 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
    $updated = db_update($table_name)
      ->expression($energy, $energy . ' * pow(2, (' . $timestamp . ' * 1.0 - ' . $time_now . ') / ' . $half_life . ')')
      ->fields(array(
      $timestamp => $time_now,
    ))
      ->condition($timestamp, $time_now, '<')
      ->condition("deleted", "0")
      ->execute();

    /* Brute deletion of the field might not be ok but the field api can handle this */
    $cuts = db_delete($table_name)
      ->condition($energy, $cut_off, '<')
      ->condition("deleted", "0")
      ->execute();
    drupal_set_message(t("Updated @num fields and culled @culled fields of @table", array(
      "@num" => $updated,
      "@culled" => $cuts,
      "@table" => $table_name,
    )));
  }
  variable_set('radioactivity_last_cron_timestamp', $timestamp);
}