farmOS/modules/farm/farm_livestock/farm_livestock_weight/farm_livestock_weight.module

1162 lines
35 KiB
Plaintext

<?php
/**
* @file
* Farm livestock weight module.
*/
/**
* Helper function for retrieving the weight of an animal.
*
* @param FarmAsset $asset
* The animal asset to get weight for.
*
* @return array
* Returns an array of quantity information about the asset's weight, based
* on its latest weight quantity log. Returns an empty array if nothing is
* found.
*/
function farm_livestock_weight($asset) {
// Load the latest log with a 'weight' quantity measurement for this asset.
$log = farm_quantity_log_asset($asset, 'weight', NULL, REQUEST_TIME, TRUE, 'farm_observation');
// if no weight observation log exists for asset
if (empty($log)) {
return array();
}
// Extract quantity data from the log.
$data = farm_quantity_log_data($log, 'weight');
// Iterate through the data and return the first one with a value.
foreach ($data as $quantity) {
if (!empty($quantity['value'])) {
return $quantity;
}
}
// If nothing was returned, return an empty array.
return array();
}
/**
* Helper function for retrieving all weight logs of an animal.
*
* @param FarmAsset $asset
* The animal asset to get weight for.
*
* @return array
* Returns an array of arrays with the following information from each weight log:
* weight, value, units, label, log
* Newest is the first, oldest last.
*/
function farm_livestock_weight_all($asset) {
// Load the logs with a 'weight' quantity measurement for this asset.
$logs = farm_quantity_log_asset($asset, 'weight', NULL, REQUEST_TIME, TRUE, 'farm_observation', FALSE);
// If only a single log was returned, wrap it in an array.
if (!is_array($logs)) {
$logs = array($logs);
}
// Start array of log weights.
$log_weights = array();
// Check that there are some logs!
if (!empty($logs)) {
foreach ($logs as $log) {
// Get weight quantity data from log.
$data = farm_quantity_log_data($log, 'weight');
foreach ($data as $quantity) {
if (!empty($quantity['value'])) {
// Save the log with the quantity info.
$quantity['log'] = $log;
// Add quantity to log weights.
$log_weights[] = $quantity;
}
}
}
}
// Return log weights.
return $log_weights;
}
/**
* Helper function for retrieving the latest daily liveweight gain for an animal
*
* @param FarmAsset $asset
* The animal asset to get daily liveweight for.
*
* @return array
* Returns an array of information around the daily liveweight gain:
* "latest_log" - The latest weight log.
* "previous_log" - The weight log recorded before the latest.
* "value" - The daily liveweight gain value.
* "units" - The unit of measure (eg kg).
* "markup" - HTML markup of the dlwg.
*/
function farm_livestock_weight_dlwg($asset) {
// Get weight data for the asset.
$weights = farm_livestock_weight_all($asset);
// Build array of Daily Liveweight Gain information.
$dlwg = array();
// At least 2 weights must be recorded to calculate Daily Liveweight gain.
if (count($weights) > 1) {
// Make sure logs use the same units.
if ($weights[0]['units'] == $weights[1]['units']) {
// Save latest weight info.
$latest_weight = $weights[0];
$latest_log = $latest_weight['log'];
// Save previous weight info.
$previous_weight = $weights[1];
$previous_log = $previous_weight['log'];
// Save units.
$units = $latest_weight['units'];
// Calculate weight difference.
$weight_difference = $latest_weight['value'] - $previous_weight['value'];
// Calculate time difference.
$timediff = $latest_log->timestamp - $previous_log->timestamp;
$timediff_days = round($timediff/86400,2);
// Calculate dlwg.
$dlwg_value = round($weight_difference/$timediff_days,3);
// Generate markup commonly output by users of this function.
// Date format
$date_format = 'M j Y';
// Build links to weight logs.
// Latest log.
$latest_log_uri = entity_uri('log', $latest_log);
$latest_log_date = date($date_format, $latest_log->timestamp);
// Previous log.
$previous_log_uri = entity_uri('log', $previous_log);
$previous_log_date = date($date_format, $previous_log->timestamp);
// Build value + units text.
$dlwg_text = $dlwg_value . ' ' . $units . '/' . t('day');
// Build "observed between" text.
$observed_text = t(
'observed between <a href="!previous_log_link">@previous_log_date</a> and <a href="!latest_log_link">@latest_log_date</a>',
array(
'!previous_log_link' => url($previous_log_uri['path']),
'@previous_log_date' => $previous_log_date,
'!latest_log_link' => url($latest_log_uri['path']),
'@latest_log_date' => $latest_log_date)
);
// Assemble markup.
$markup = '<p><strong>' . t('Daily liveweight gain') . ':</strong> ' . $dlwg_text . ' (' . $observed_text . ')</p>';
// Build array to return.
$dlwg = array("latest_log" => $latest_log, "previous_log" => $previous_log, "value" => $dlwg_value, "units" => $units, 'markup' => $markup);
}
}
return $dlwg;
}
/**
* Create a weight measurement log associated with an animal.
*
* @param array $assets
* The assets to add a weight measurement to.
* @param string $weight
* The animal's current weight.
* @param string $units
* The units of measurement.
* @param int $timestamp
* The timestamp of the measurement. Defaults to the current time.
* @param bool $done
* Boolean indicating whether or not the log should be marked "done".
* Defaults to TRUE.
*
* @return \Log
* Returns the log that was created.
*/
function farm_livestock_weight_set($assets, $weight, $units, $timestamp = REQUEST_TIME, $done = TRUE) {
// The log will be an observation.
$log_type = 'farm_observation';
// Set the name to: "Weight of [assets] is [weight] [units]".
$assets_summary = farm_log_entity_label_summary('farm_asset', $assets);
$log_name = t('Weight of !assets is !weight !units', array('!assets' => $assets_summary, '!weight' => $weight, '!units' => $units));
// If $assets isn't an array, wrap it.
if (!is_array($assets)) {
$assets = array($assets);
}
// Assemble an array of measurements.
$measurements = array(
array(
'measure' => 'weight',
'value' => $weight,
'units' => $units,
'label' => '',
),
);
// Create a new log entity.
$log = farm_quantity_log_create($log_type, $log_name, $timestamp, $done, $assets, $measurements);
// Return the log.
return $log;
}
/**
* Implements hook_menu().
*/
function farm_livestock_weight_menu() {
$items = array();
// Farm asset uri for the view path
$farm_asset_uri = 'farm/asset/%farm_asset';
$farm_asset_uri_argument_position = 2;
// Animal asset report tab.
$items[$farm_asset_uri . '/weight'] = array(
'title' => t('Weight'),
'page callback' => 'farm_livestock_weight_individual_report',
'page arguments' => array($farm_asset_uri_argument_position),
'access callback' => 'farm_livestock_weight_individual_report_access',
'access arguments' => array($farm_asset_uri_argument_position),
'file' => 'farm_livestock_weight.report.inc',
'type' => MENU_LOCAL_TASK,
'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
);
// Animal group report form.
$items['farm/report/weight'] = array(
'title' => t('Animal Weights'),
'page callback' => 'drupal_get_form',
'page arguments' => array('farm_livestock_weight_group_report_form'),
'access arguments' => array('view farm reports'),
'type' => MENU_LOCAL_TASK,
);
return $items;
};
/**
* Individual report view access callback.
*
* @param $farm_asset
* The asset to check access for.
*
* @return bool
* Returns boolean value indicating whether or not access is granted.
*/
function farm_livestock_weight_individual_report_access($farm_asset) {
// If the asset is not an animal, deny access.
if ($farm_asset->type != 'animal') {
return FALSE;
}
// Finally, check to see if the user has access to the asset.
return farm_asset_access('view', $farm_asset);
}
/**
* Animal group report form.
*/
function farm_livestock_weight_group_report_form($form, &$form_state) {
// Set the page title.
drupal_set_title(t('Animal Weights'));
// Build an entity field query of group assets.
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'farm_asset');
$query->entityCondition('bundle', 'group');
$query->propertyOrderBy('name', 'ASC');
// Execute the query and build a list of options.
$options = array();
$result = $query->execute();
if (isset($result['farm_asset'])) {
$group_ids = array_keys($result['farm_asset']);
$groups = farm_asset_load_multiple($group_ids);
if (!empty($groups)) {
foreach ($groups as $group) {
if (!empty($group->id)) {
$label = entity_label('farm_asset', $group);
if ($group->archived) {
$date = strftime('%Y-%m-%d', $group->archived);
$label = $label . ' (' . t('archived') . ' ' . $date . ')';
}
$options[$group->id] = $label;
}
}
}
}
// Define the input fieldset
$form['input'] = array(
'#type' => 'fieldset',
'#title' => t('Input Form'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
// Create a select field for the groups.
$form['input']['group'] = array(
'#type' => 'select',
'#title' => t('Animal Group'),
'#description' => t('Select the group(s) of animals to include in the weight report.'),
'#options' => $options,
'#required' => TRUE,
'#multiple' => TRUE,
);
$form['input']['archived'] = array(
'#type' => 'select',
'#title' => t('Archived'),
'#options' => array(0 => t('No'), 1 => t('Yes'), 2 => '-' . t('Any') . '-'),
'#default_value' => 0,
);
$form['input']['flags'] = array(
'#type' => 'select',
'#title' => t('Flags'),
'#options' => farm_flags_field_allowed_values(),
'#multiple' => TRUE,
);
// Provide a default date in the format YYYY-MM-DD.
$format = 'Y-m-d';
$current_date = date($format, REQUEST_TIME);
$form['input']['birth'] = array(
'#type' => 'fieldset',
'#title' => t('Birth Date'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['input']['birth']['earliest_birth'] = array(
'#type' => 'date_select',
'#title' => t('Earliest Birth'),
'#default_value' => '',
'#date_year_range' => '-10:+1',
'#date_format' => $format,
'#date_label_position' => 'within',
);
$form['input']['birth']['latest_birth'] = array(
'#type' => 'date_select',
'#title' => t('Latest Birth'),
'#default_value' => '',
'#date_year_range' => '-10:+1',
'#date_format' => $format,
'#date_label_position' => 'within',
);
$form['input']['start_date'] = array(
'#type' => 'date_select',
'#title' => t('Start date'),
'#description' => t('First recorded date of animal weights to include..'),
'#default_value' => '',
'#date_year_range' => '-10:+1',
'#date_format' => $format,
'#date_label_position' => 'within',
);
$form['input']['end_date'] = array(
'#type' => 'date_select',
'#title' => t('End date'),
'#description' => t('Last recorded date of animal weights to include..'),
'#default_value' => $current_date,
'#date_year_range' => '-10:+1',
'#date_format' => $format,
'#date_label_position' => 'within',
);
// Add submit button to generate report.
$form['input']['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
'#submit' => array('farm_livestock_weight_group_report_form_submit'),
);
// Add submit button to download CSV.
$form['input']['csv'] = array(
'#type' => 'submit',
'#value' => t('CSV'),
'#submit' => array('farm_livestock_weight_group_report_csv'),
);
// Display results from the form.
if (!empty($form_state['results_table'])) {
// Hide the input fieldset
$form['input']['#collapsed'] = TRUE;
// Create a results fieldset.
$form['results'] = array(
'#type' => 'fieldset',
'#title' => t('Results'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
// Display the Graphs.
$graphs = '<div class="farm-livestock-weight-group-report-graphs">' . implode('', $form_state['graph-markup']) . '</div>';
// Add JS and CSS to build the graphs.
drupal_add_js($form_state['graph-settings'], 'setting');
drupal_add_js(drupal_get_path('module', 'farm_livestock_weight') . '/farm_livestock_weight_group_graph.js');
drupal_add_js('https://cdn.plot.ly/plotly-latest.min.js', 'external');
drupal_add_css(drupal_get_path('module', 'farm_livestock_weight') . '/farm_livestock_weight.css');
$form['results']['graphs'] = array('#markup' => $graphs);
// Display the HTML Table.
$form['results']['results_table'] = array('#markup' => $form_state['results_table']);
}
return $form;
}
/**
* Submit handler for the weight report form
*/
function farm_livestock_weight_group_report_form_submit($form, &$form_state) {
$results = farm_livestock_weight_group_report($form_state);
$form_state['graph-settings'] = $results['graph-settings'];
$form_state['graph-markup'] = $results['graph-markup'];
$form_state['results_table'] = $results['table'];
$form_state['rebuild'] = TRUE;
}
/**
* Generate Animal Weight Group Report
*/
function farm_livestock_weight_group_report(&$form_state) {
// Get the submitted group IDs to include in the report.
$group_ids = $form_state['values']['group'];
// Check if we should include archived assets.
$include_archived = (bool) $form_state['values']['archived'];
$only_archived = $form_state['values']['archived'] == 1;
// Get list of flags to filter by.
$flags = $form_state['values']['flags'];
// Get date of birth filters.
$earliest_birth = strtotime($form_state['values']['earliest_birth']);
$latest_birth = strtotime($form_state['values']['latest_birth']);
// Get the start and end dates.
$start_date = strtotime($form_state['values']['start_date']);
$end_date = strtotime($form_state['values']['end_date']);
// Array to store dates of animal weight logs for CSV export.
$date_format = 'Y-m-d';
$all_log_dates = array();
// Array to store animals and log data
$animals = array();
// Loop through each group, its members, and all weight logs.
foreach ($group_ids as $id) {
// Load the farm group asset.
$group = farm_asset_load($id);
// Load the farm group members.
$members = farm_group_members($group, REQUEST_TIME, TRUE, $include_archived);
// Loop through members.
foreach ($members as $asset) {
// If member is not an animal, bail.
if ($asset->type != 'animal') {
continue;
}
// Skip non-archived assets if only displaying archived assets.
if ($only_archived && !$asset->archived) {
continue;
}
// Check if asset has required flags.
if (!empty($flags)) {
// Compare asset flags to required flags.
$asset_flags = farm_flags_load($asset);
$diff = array_diff($flags, $asset_flags);
// Skip the asset if it doesn't have required flags.
if (!empty($diff)) {
continue;
}
}
// Check if a birth date filter is specified.
if ($earliest_birth || $latest_birth) {
// Get the assets birth date.
$birth_date = NULL;
if (!empty($asset->field_farm_date[LANGUAGE_NONE][0]['value'])) {
$birth_date = $asset->field_farm_date[LANGUAGE_NONE][0]['value'];
}
// Skip assets without a birth date.
if (empty($birth_date)) {
continue;
}
// Skip assets born before earliest birth date.
if ($earliest_birth) {
if ($birth_date < $earliest_birth) {
continue;
}
}
// Skip assets born after latest birth date.
if ($latest_birth) {
if ($birth_date > $latest_birth) {
continue;
}
}
}
// Save the animal info
$asset->group = $group;
// Load the group member's weights
$time = REQUEST_TIME;
if (!empty($end_date)) {
$time = $end_date;
}
$logs = farm_quantity_log_asset($asset, 'weight', NULL, $time, TRUE, 'farm_observation', FALSE);
// Array to save log dates for this one animal.
$log_dates = array();
// Array to save data from animal logs.
$all_log_data = array();
// Loop through weight logs.
foreach ($logs as $log) {
// Get the date of the log from the timestamp.
$log_date = date($date_format, $log->timestamp);
// Check that the log timestamp fits the date parameters. Note that we
// only need to check the start date bound, because end date is already
// filtered by farm_quantity_log_asset().
if ($log->timestamp < $start_date) {
continue;
}
// Add the log date to the array if not already included.
if (!in_array($log_date, $log_dates)){
$log_dates[] = $log_date;
} else {
continue;
}
// Extract quantity data from the log.
$data = farm_quantity_log_data($log, 'weight');
// Iterate through the data and return the first one with a value.
foreach ($data as $quantity) {
if (!empty($quantity['value'])) {
$value = $quantity['value'];
$units = $quantity['units'];
// Add the log data to array of logs.
$log_data = array();
$log_data['date'] = $log_date;
$log_data['value'] = $value;
$log_data['units'] = $units;
$all_log_data[]= $log_data;
}
}
}
// Merge animal's log dates with all_log_dates.
$all_log_dates = array_unique( array_merge( $all_log_dates, $log_dates));
// Save all log data with the animal.
$asset->all_log_data = $all_log_data;
// Add animal data to array of all animals.
$animals[] = $asset;
}
}
// Sort all collected log_dates.
sort($all_log_dates);
// Create a header for CSV and HTML Table
$header = array(t('Asset ID'), t('Asset Name'), t('Group'));
// Add columns for each date collected.
foreach ($all_log_dates as $date) {
$header[] = t('Date - ') . $date ;
$header[] = t('Weight');
$header[] = t('Units');
}
// Add the CSV header.
$csvdata = implode(',', $header) . PHP_EOL;
// Initialize array for Date Averages
$group_date_averages = array();
foreach($group_ids as $id) {
$group_date_averages[$id] = array(
'group' => farm_asset_load($id),
'dates' => array(),
);
}
foreach ($animals as $animal) {
// Add a row of data.
$row = array();
$name_label = htmlspecialchars(entity_label('farm_asset', $animal));
if ($animal->archived) {
$date = strftime('%Y-%m-%d', $animal->archived);
$name_label = $name_label . ' (' . t('archived') . ' ' . $date . ')';
}
$row[] = $animal->id;
$row[] = $name_label;
$row[] = htmlspecialchars(entity_label('farm_asset', $animal->group));
// Save the logs.
$logs = $animal->all_log_data;
// Skip adding logs if the animal has no logs
if (sizeof($logs) == 0) {
// Add Animal info to results.
$table_data[] = $row;
$csvdata .= implode(',', $row) . PHP_EOL;
continue;
}
// Sort the logs by date.
usort($logs, "farm_livestock_weight_log_array_sort_date");
// Save a counter for which log to compare.
$curr_log_index = 0;
// Save a counter for which column to compare.
$curr_column_index = 0;
// Walk through each column and add log data if log date == column date.
// Note that each date requires 3 columns in the CSV file to display the
// date, value and units of recorded log weights.
while($curr_log_index < sizeof($logs) && $curr_column_index < sizeof($all_log_dates)) {
// Conert the dates to times for easier comparison.
$column_time = strtotime($all_log_dates[$curr_column_index]);
$log_time = strtotime($logs[$curr_log_index]['date']);
// If the log_time is less than column_time, then there are multiple logs
// on the same date for the animal. The first one has already been saved,
// skip any additional logs with the same date.
if ($column_time > $log_time) {
$curr_log_index += 1;
// Set empty values if the times don't match.
// Move to next column
} else if ($column_time != $log_time) {
$row[] = '';
$row[] = '';
$row[] = '';
$curr_column_index += 1;
} else {
$log_date = $logs[$curr_log_index]['date'];
$log_value = $logs[$curr_log_index]['value'];
$log_units = $logs[$curr_log_index]['units'];
// Save the log date, value and units if the times match.
$row[] = $log_date;
$row[] = $log_value;
$row[] = $log_units;
// For displaying graphs of average weights
// Tally the weight of the animal in the All Log Dates array
// Initialize the Group's average weight array for the log date.
if (!isset($group_date_averages[$animal->group->id]['dates'][$log_date])) {
$group_date_averages[$animal->group->id]['dates'][$log_date] = array(
'units' => $log_units,
'total_weight' => $log_value,
'animal_count' => 1,
);
} else {
$group_date_averages[$animal->group->id]['dates'][$log_date]['total_weight'] += $log_value;
$group_date_averages[$animal->group->id]['dates'][$log_date]['animal_count'] += 1;
}
// Move to next column, and next log.
$curr_column_index += 1;
$curr_log_index += 1;
}
}
// Add row to HTML Table
$table_data[] = $row;
// Add to CSV string
$csvdata .= implode(',', $row) . PHP_EOL;
}
$table = '<div class="alert alert-danger">' . t('No animal assets match the above criteria.') . '</div>';
if (!empty($table_data)) {
// Create HTML Table
$table = theme('table', array('header' => $header, 'rows' => $table_data));
}
// Create the div to hold report graphs.
$graph_markup = array();
// Create a graph object to pass to JS.
$graphs = array();
// Create graphs for each group
foreach($group_date_averages as $group){
$group_name = $group['group']->name;
// Sort the array by date
ksort($group['dates']);
$dates = array_keys($group['dates']);
for($i = 0; $i < count($group['dates']); $i++){
$date = $dates[$i];
// Calculate average weight.
$date_average = $group['dates'][$date]['total_weight'] / $group['dates'][$date]['animal_count'];
$group['dates'][$date]['average_weight'] = $date_average;
// Calculate Average Daily Gain after the first date.
if ($i > 0) {
$previous_date = $dates[$i -1];
$previous_average = $group['dates'][$previous_date]['average_weight'];
// Calculate gain between the two dates.
$gain = $date_average - $previous_average;
// Calculate days elapsed.
$dStart = new DateTime($previous_date);
$dEnd = new DateTime($date);
$days_elapsed = (int) $dStart->diff($dEnd)->format("%a");
// Save the daily gain value within the 'date' array.
$group['dates'][$date]['gain'] = $gain / $days_elapsed;
}
}
// Create Average Weight Graph
$graph = array(
'name' => t('Average Weight - ') . $group_name,
'id' => 'farm-livestock-average-weight-' . $group_name . '-graph',
'data' => $group['dates'],
);
$graphs[] = $graph;
$graph_markup[] = '<div id="farm-livestock-average-weight-' . $group_name . '-graph" class="farm-report-graph"></div>';
}
$graph_settings = array(
'farm_livestock_report' => array(
'graphs' => $graphs,
),
);
return array(
'graph-settings' => $graph_settings,
'graph-markup' => $graph_markup,
'table' => $table,
'csv' => $csvdata,
);
}
/**
* Animal Weight Group Report CSV Export
*/
function farm_livestock_weight_group_report_csv($form, &$form_state){
$results = farm_livestock_weight_group_report($form_state);
drupal_add_http_header('Content-Type', 'text/csv');
drupal_add_http_header('Content-Disposition', 'attachment; filename=animal_weights.csv');
print $results['csv'];
drupal_exit();
}
/**
* Helper function to sort an array of logs by timestamp
*/
function farm_livestock_weight_log_array_sort_date($a, $b) {
return strtotime($a['date']) - strtotime($b['date']);
}
/**
* Implements hook_entity_view_alter().
*/
function farm_livestock_weight_entity_view_alter(&$build, $type) {
// If it's not a farm_asset, or if the entity object is not available, bail.
if ($type != 'farm_asset' || empty($build['#entity'])) {
return;
}
// Alias the asset variable.
$asset = $build['#entity'];
$asset_uri = entity_uri('farm_asset', $asset);
// If it isn't an animal asset, bail.
if ($asset->type != 'animal') {
return;
}
// Get the animal's current weight.
$weight = farm_livestock_weight($asset);
// If a weight measurement isn't available, bail.
if (empty($weight)) {
return;
}
// Get the value and the units.
$value = !empty($weight['value']) ? $weight['value'] : '';
$units = !empty($weight['units']) ? $weight['units'] : '';
// If the animal has an inventory greater than 1, add "(average)".
$inventory = farm_inventory($asset);
$average_text = '';
if ($inventory > 1) {
$average_text .= ' (' . t('average') . ')';
}
// Build the weight display.
$output = '<strong>' . t('Weight') . ':</strong> ' . $value . ' ' . $units . $average_text . '<a href="' . url($asset_uri['path'] . '/weight') . t('"> (weight report) </a>');
// Load the daily live weight gain.
$dlwg = farm_livestock_weight_dlwg($asset);
if (!empty($dlwg)){
// Add the dlwg markup.
$output .= $dlwg['markup'];
}
// Add it to the build array.
$build['weight'] = array(
'#markup' => $output,
'#prefix' => '<div class="weight">',
'#suffix' => '</div>',
'#weight' => -120,
);
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function farm_livestock_weight_form_farm_asset_form_alter(&$form, &$form_state, $form_id) {
// Get the farm asset entity from the form.
$asset = $form['farm_asset']['#value'];
// If the asset is not an animal, bail.
if ($asset->type != 'animal') {
return;
}
// Get the animal's current weight.
$weight = farm_livestock_weight($asset);
// Add a field for setting the animal's current weight.
$form['weight'] = array(
'#type' => 'fieldset',
'#title' => t('Weight'),
'#description' => t('Set the current weight for this animal. If this record is used to represent multiple animals, enter their average weight. An observation log will be created automatically to record the weight.'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#weight' => 100,
'#tree' => TRUE,
);
$form['weight']['value'] = array(
'#type' => 'textfield',
'#title' => t('Weight'),
'#default_value' => !empty($weight['value']) ? $weight['value'] : '',
'#element_validate' => array('element_validate_number'),
);
$form['weight']['units'] = array(
'#type' => 'textfield',
'#title' => t('Units'),
'#autocomplete_path' => 'taxonomy/autocomplete/field_farm_quantity_units',
'#default_value' => !empty($weight['units']) ? $weight['units'] : '',
);
$form['actions']['submit']['#validate'][] = 'farm_livestock_weight_asset_form_validate';
$form['actions']['submit']['#submit'][] = 'farm_livestock_weight_asset_form_submit';
$form['#group_children']['weight'] = 'group_farm_general';
}
/**
* Validate handler for processing the animal weight field.
*
* @param array $form
* The form array.
* @param array $form_state
* The form state array.
*/
function farm_livestock_weight_asset_form_validate(array $form, array &$form_state) {
// If units are set, but not weight, show an error.
if (empty($form_state['values']['weight']['value']) && !empty($form_state['values']['weight']['units'])) {
form_set_error('weight][value', t('Both weight and units must be specified.'));
}
}
/**
* Submit handler for processing the animal weight field.
*
* @param array $form
* The form array.
* @param array $form_state
* The form state array.
*/
function farm_livestock_weight_asset_form_submit(array $form, array &$form_state) {
// Only proceed if weight has a value.
if (empty($form_state['values']['weight']['value'])) {
return;
}
// Only proceed if the value is not the default value.
if ($form_state['values']['weight']['value'] == $form['weight']['value']['#default_value']) {
return;
}
// If an asset doesn't exist, bail.
if (empty($form_state['values']['farm_asset'])) {
return;
}
// Grab the asset, weight, and units.
$asset = $form_state['values']['farm_asset'];
$weight = $form_state['values']['weight']['value'];
$units = $form_state['values']['weight']['units'];
// Create an observation log to set the weight.
farm_livestock_weight_set($asset, $weight, $units);
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function farm_livestock_weight_form_farm_livestock_birth_form_alter(&$form, &$form_state, $form_id) {
// Add birth weight fields to children fieldsets in birth quick form.
$child_fieldsets = element_children($form['birth']['child']);
if (!empty($child_fieldsets)) {
foreach ($child_fieldsets as $i) {
$form['birth']['child'][$i]['weight'] = array(
'#type' => 'textfield',
'#title' => t('Birth weight'),
'#element_validate' => array('element_validate_number'),
'#weight' => 20,
);
$form['birth']['child'][$i]['units'] = array(
'#type' => 'textfield',
'#title' => t('Weight units'),
'#autocomplete_path' => 'taxonomy/autocomplete/field_farm_quantity_units',
'#weight' => 21,
);
}
}
// Add submit function.
$form['#submit'][] = 'farm_livestock_weight_form_farm_livestock_birth_form_submit';
}
/**
* Submit function for livestock birth form to set child birth weights.
*/
function farm_livestock_weight_form_farm_livestock_birth_form_submit($form, &$form_state) {
// Iterate through child animal assets that were created during form
// submission and create weight measurement logs..
if (!empty($form_state['storage']['children'])) {
foreach ($form_state['storage']['children'] as $delta => $child_asset) {
if (!empty($form_state['values']['birth']['child'][$delta]['weight'])) {
$weight = $form_state['values']['birth']['child'][$delta]['weight'];
$units = $form_state['values']['birth']['child'][$delta]['units'];
$timestamp = strtotime($form_state['values']['birth']['timestamp']);
farm_livestock_weight_set($child_asset, $weight, $units, $timestamp);
}
}
}
}
/**
* Implements hook_action_info().
*/
function farm_livestock_weight_action_info() {
return array(
'farm_livestock_weight_action' => array(
'type' => 'farm_asset',
'label' => t('Weight'),
'configurable' => TRUE,
'triggers' => array('any'),
'aggregate' => TRUE,
),
);
}
/**
* Configuration form for farm_livestock_weight_action.
*
* @param array $context
* The context passed into the action form function.
* @param array $form_state
* The form state passed into the action form function.
*
* @return array
* Returns a form array.
*/
function farm_livestock_weight_action_form(array $context, array $form_state) {
// Date field.
$form['date'] = array(
'#type' => 'date_select',
'#title' => t('Date'),
'#date_format' => 'M j Y',
'#date_type' => DATE_FORMAT_UNIX,
'#date_year_range' => '-10:+3',
'#default_value' => date('Y-m-d H:i', REQUEST_TIME),
'#required' => TRUE,
);
// Weight.
$form['weight'] = array(
'#type' => 'textfield',
'#title' => t('Weight'),
'#description' => t('Enter the weight of the animal(s). If multiple animals are selected, enter the average animal weight.'),
'#element_validate' => array('element_validate_number'),
'#required' => TRUE,
);
// Units.
$form['units'] = array(
'#type' => 'textfield',
'#title' => t('Units'),
'#autocomplete_path' => 'taxonomy/autocomplete/field_farm_quantity_units',
'#required' => TRUE,
);
// Return the form.
return $form;
}
/**
* Submit handler for farm_livestock_weight_action configuration form.
*
* @param array $form
* The form array.
* @param array $form_state
* The form state array.
*
* @return array
* Returns an array that will end up in the action's context.
*/
function farm_livestock_weight_action_submit(array $form, array $form_state) {
// Start to build the context array.
$context = array();
// Convert the date to a timestamp.
$timestamp = strtotime($form_state['values']['date']);
// The action form only includes month, day, and year. If the measurement is
// today, then we assume that the current time should also be included.
if (date('Ymd', $timestamp) == date('Ymd', REQUEST_TIME)) {
$context['timestamp'] = REQUEST_TIME;
}
// Otherwise, the measurement is in the past/future, so don't include a time.
else {
$context['timestamp'] = $timestamp;
}
// Add the weight and units fields.
$context['weight'] = $form_state['values']['weight'];
$context['units'] = $form_state['values']['units'];
// Return the context array.
return $context;
}
/**
* Action function for farm_livestock_weight_action.
*
* Creates a new weight observation log for the specified assets.
*
* @param array $assets
* An array of asset entities.
* @param array $context
* Array with parameters for this action.
*/
function farm_livestock_weight_action(array $assets, $context = array()) {
// If we're missing assets, weight, units, or a timestamp, bail.
if (empty($assets) || empty($context['weight']) || empty($context['units']) || empty($context['timestamp'])) {
drupal_set_message(t('Could not set weights because required information was missing.'), 'error');
return;
}
// Set the animal weights.
farm_livestock_weight_set($assets, $context['weight'], $context['units'], $context['timestamp']);
}
/**
* Implements hook_views_api().
*/
function farm_livestock_weight_views_api($module = NULL, $api = NULL) {
return array("api" => "3.0");
}
/**
* Implements hook_views_default_views_alter().
*/
function farm_livestock_weight_views_default_views_alter(&$views) {
// Add the Weight VBO operation to the animals view.
if (!empty($views['farm_animals'])) {
$views['farm_animals']->display['default']->display_options['fields']['views_bulk_operations']['vbo_operations'] += [
'action::farm_livestock_weight_action' => [
'selected' => 1,
'skip_confirmation' => 0,
'skip_permission_check' => 1,
'override_label' => 0,
'label' => '',
],
];
}
}