farm_quantity_log.module in farmOS 7
Farm quantity log module.
File
modules/farm/farm_quantity/farm_quantity_log/farm_quantity_log.moduleView source
<?php
/**
* @file
* Farm quantity log module.
*/
/**
* Extract quantity data from a log, with optional filters for measure/label.
*
* @param Log $log
* The log object to extract quantity information from.
* @param string $measure
* The quantity measure to search for (ie: weight).
* @param string $label
* The quantity label to search for.
*
* @return array
* Returns a structured array of information about the quantities recorded
* on the log.
*/
function farm_quantity_log_data(Log $log, $measure = NULL, $label = NULL) {
// Start with an empty data array.
$data = array();
// Load the log entity metadata wrapper.
$log_wrapper = entity_metadata_wrapper('log', $log);
// If there are no quantities, bail.
if (empty($log_wrapper->field_farm_quantity)) {
return $data;
}
// Iterate over the quantities.
foreach ($log_wrapper->field_farm_quantity as $quantity) {
// If a measure is specified, and it doesn't match, skip this one.
if (!empty($measure) && $quantity->field_farm_quantity_measure
->value() != $measure) {
continue;
}
// If a label is specified, and it doesn't match, skip this one.
if (!empty($label) && $quantity->field_farm_quantity_label
->value() != $label) {
continue;
}
// Get the quantity value and convert to a decimal.
$value = '';
if (!empty($quantity->field_farm_quantity_value
->value())) {
if (!empty($quantity->field_farm_quantity_value
->value()['fraction'])) {
$value = $quantity->field_farm_quantity_value
->value()['fraction']
->toDecimal(0, TRUE);
}
}
// Get the quantity units name.
$units = '';
if (!empty($quantity->field_farm_quantity_units
->value())) {
if (!empty($quantity->field_farm_quantity_units
->value()->name)) {
$units = $quantity->field_farm_quantity_units
->value()->name;
}
}
// Add quantity data to the array.
$data[] = array(
'measure' => $quantity->field_farm_quantity_measure
->value(),
'value' => $value,
'units' => $units,
'label' => $quantity->field_farm_quantity_label
->value(),
);
}
// Return the data.
return $data;
}
/**
* Load logs for an asset with a given quantity measure and/or label.
*
* @param FarmAsset $asset
* The farm_asset object to look for.
* @param string $measure
* The quantity measure to search for (ie: weight).
* @param string $label
* The quantity label to search for.
* @param int $time
* Unix timestamp limiter. Only logs before this time will be included.
* Defaults to the current time. Set to 0 to load the absolute last.
* @param bool|null $done
* Whether or not to only show logs that are marked as "done". TRUE will limit
* to logs that are done, and FALSE will limit to logs that are not done. If
* this is set to NULL, no filtering will be applied. Defaults to TRUE.
* @param string $type
* The log type to filter by. If empty, no filtering will be applied.
* @param bool $single
* Whether or not to limit the query to a single result. Defaults to TRUE.
*
* @return Log|array|bool
* Returns a log entity, or an array of them. FALSE if something goes wrong.
*/
function farm_quantity_log_asset(FarmAsset $asset, $measure = NULL, $label = NULL, $time = REQUEST_TIME, $done = TRUE, $type = NULL, $single = TRUE) {
// If the asset doesn't have an ID (for instance if it is new and hasn't been
// saved yet), bail.
if (empty($asset->id)) {
return FALSE;
}
// Make a query for loading the latest quantity log.
$query = farm_quantity_log_asset_query($asset->id, $measure, $label, $time, $done, $type, $single);
// Execute the query and gather the log id.
$result = $query
->execute();
// Return array of log objects. $single = FALSE
if (empty($single)) {
$log_item_ids = $result
->fetchCol();
$logs = entity_load('log', $log_item_ids);
return $logs;
}
else {
if (!empty($single)) {
$log_id = $result
->fetchField();
if (!empty($log_id)) {
return log_load($log_id);
}
}
}
// If all else fails, return FALSE.
return FALSE;
}
/**
* Build a query to find logs of an asset that defines a quantity.
*
* @param int $asset_id
* The asset id to search for.
* @param string $measure
* The quantity measure to search for (ie: weight).
* @param string $label
* The quantity label to search for.
* @param int $time
* Unix timestamp limiter. Only logs before this time will be included.
* Defaults to the current time. Set to 0 to load the absolute last.
* @param bool|null $done
* Whether or not to only show logs that are marked as "done". TRUE will limit
* to logs that are done, and FALSE will limit to logs that are not done. If
* this is set to NULL, no filtering will be applied. Defaults to TRUE.
* @param string|null $type
* The log type to filter by. If this is NULL, no filtering will be applied.
* @param bool $single
* Whether or not to limit the query to a single result. Defaults to TRUE.
*
* @return \SelectQuery
* Returns a SelectQuery object.
*/
function farm_quantity_log_asset_query($asset_id, $measure = NULL, $label = NULL, $time = REQUEST_TIME, $done = TRUE, $type = NULL, $single = TRUE) {
/**
* Please read the comments in farm_log_asset_query() to understand how this
* works, and to be aware of the limitations and responsibilities we have in
* this function with regard to sanitizing query inputs.
*/
// Use the farm_log_asset_query() helper function to start a query object.
$query = farm_log_asset_query($asset_id, $time, $done, $type, $single);
// Add a query tag to identify where this came from.
$query
->addTag('farm_quantity_log_asset_query');
// Add quantity filters to the query using a helper function.
farm_quantity_log_query_add_filters($query, $measure, $label);
// Return the query object.
return $query;
}
/**
* Load all quantity logs that match certain criteria.
*
* @param string $measure
* The quantity measure to search for (ie: weight).
* @param string $label
* The quantity label to search for.
* @param int $start_time
* Unix timestamp limiter. Only logs after this time will be included.
* Defaults to 0, which will not limit the logs at all.
* @param int $end_time
* Unix timestamp limiter. Only logs before this time will be included.
* Defaults to the current time. Set to 0 to load the absolute last.
* @param bool|null $done
* Whether or not to only show logs that are marked as "done". TRUE will limit
* to logs that are done, and FALSE will limit to logs that are not done. If
* this is set to NULL, no filtering will be applied. Defaults to TRUE.
* @param string|null $type
* The log type to filter by. If this is NULL, no filtering will be applied.
* @param string $category
* The log category to search for.
*
* @return array
* Returns an array of log entities.
*/
function farm_quantity_log($measure = NULL, $label = NULL, $start_time = 0, $end_time = REQUEST_TIME, $done = TRUE, $type = NULL, $category = NULL) {
// Make a query for loading quantity logs.
$query = farm_quantity_log_query($measure, $label, $start_time, $end_time, $done, $type, $category);
// Execute the query and gather the log ids.
$result = $query
->execute();
$log_ids = array();
foreach ($result as $row) {
if (!empty($row->id)) {
$log_ids[] = $row->id;
}
}
// If there are log IDs, load the logs.
if (!empty($log_ids)) {
return log_load_multiple($log_ids);
}
return array();
}
/**
* Build a query to find logs that define quantity measurements.
*
* @param string $measure
* The quantity measure to search for (ie: weight).
* @param string $label
* The quantity label to search for.
* @param int $start_time
* Unix timestamp limiter. Only logs after this time will be included.
* Defaults to 0, which will not limit the logs at all.
* @param int $end_time
* Unix timestamp limiter. Only logs before this time will be included.
* Defaults to the current time. Set to 0 to load the absolute last.
* @param $done
* Whether or not to only show logs that are marked as "done". TRUE will limit
* to logs that are done, and FALSE will limit to logs that are not done. If
* any other value is used, no filtering will be applied. Defaults to TRUE.
* @param string|null $type
* The log type to filter by. If this is NULL, no filtering will be applied.
* @param string $category
* The log category to search for.
*
* @return \SelectQuery
* Returns a SelectQuery object.
*/
function farm_quantity_log_query($measure = NULL, $label = NULL, $start_time = 0, $end_time = REQUEST_TIME, $done = TRUE, $type = NULL, $category = NULL) {
/**
* Please read the comments in farm_log_query() to understand how this works,
* and to be aware of the limitations and responsibilities we have in this
* function with regard to sanitizing query inputs.
*/
// Use the farm_log_query() helper function to start a query object.
$query = farm_log_query($end_time, $done, $type, FALSE);
// Add a query tag to identify where this came from.
$query
->addTag('farm_quantity_log_query');
// Add quantity filters to the query using a helper function.
farm_quantity_log_query_add_filters($query, $measure, $label);
// Ensure $start_time is valid, because it may be used directly in the query
// string. This is defensive code. See note about views_join_subquery above.
// Similar logic is used for the $end_time in farm_log_query().
// In this case, we want to make sure that it is numeric AND that it is not
// greater than the end time.
if (!is_numeric($start_time) || $start_time > $end_time) {
$start_time = 0;
}
// If $start_time is not zero, limit to only logs after it. This allows the
// absolute first log to be found by setting $start_time to zero.
// Similar logic is used for the $end_time in farm_log_query().
if ($start_time !== 0) {
$query
->where('ss_log.timestamp >= ' . $start_time);
}
// If $category is not empty, load the category ID, then join in the log
// category field data and limit the query to logs with a matching category.
if (!empty($category)) {
$category_term = farm_term($category, 'farm_log_categories', FALSE);
if (!empty($category_term->tid)) {
$query
->innerJoin('field_data_field_farm_log_category', 'ss_fdfflc', "ss_fdfflc.entity_type = 'log' AND ss_fdfflc.entity_id = ss_log.id AND ss_fdfflc.deleted = 0");
$query
->where("ss_fdfflc.field_farm_log_category_tid = '" . $category_term->tid . "'");
}
}
// Return the query object.
return $query;
}
/**
* Helper function for adding joins and filters to a quantity log query.
*
* @param \SelectQuery $query
* The query object to alter.
* @param string $measure
* The quantity measure to search for (ie: weight).
* @param string $label
* The quantity label to search for.
*/
function farm_quantity_log_query_add_filters(&$query, $measure = NULL, $label = NULL) {
// Ensure that $measure and $label are valid strings, because we use them
// directly in the query's WHERE statements below. This is defensive code.
// See note about views_join_subquery in farm_log_asset_query().
if (!is_null($measure)) {
$measures = farm_quantity_measure_options();
if (!array_key_exists($measure, $measures)) {
$measure = '';
}
}
if (!is_null($label)) {
$label = db_like($label);
}
// Add the log ID field.
$query
->addField('ss_log', 'id');
// Join in the Quantity field collection. Use an inner join to exclude logs
// that do not have quantity field collection attached.
$query
->innerJoin('field_data_field_farm_quantity', 'ss_fdffq', "ss_fdffq.entity_type = 'log' AND ss_fdffq.entity_id = ss_log.id AND ss_fdffq.deleted = 0");
// Filter to only include logs with a matching measure. Use an inner join to
// exclude logs that do not have a measure.
if (!empty($measure)) {
$query
->innerJoin('field_data_field_farm_quantity_measure', 'ss_fdffqm', "ss_fdffqm.entity_id = ss_fdffq.field_farm_quantity_value AND ss_fdffqm.deleted = 0");
$query
->where("ss_fdffqm.field_farm_quantity_measure_value = '" . $measure . "'");
}
// Filter to only include logs with a matching label. Use an inner join to
// exclude logs that do not have a label.
if (!empty($label)) {
$query
->innerJoin('field_data_field_farm_quantity_label', 'ss_fdffql', "ss_fdffql.entity_id = ss_fdffq.field_farm_quantity_value AND ss_fdffql.deleted = 0");
$query
->where("ss_fdffql.field_farm_quantity_label_value = '" . $label . "'");
}
}
/**
* Helper function for creating a farm quantity measurement log.
*
* @param string $type
* The log type machine name.
* @param string $name
* Optionally specify a name for the new log.
* @param int $timestamp
* The timestamp of the log (defaults to REQUEST_TIME).
* @param bool $done
* Boolean indicating whether or not the log is done.
* @param array $assets
* An array of assets to reference in the log.
* @param array $measurements
* An array of measurements to add to the log. Example:
* $measurements = array(
* array(
* 'measure' => 'weight',
* 'value' => 100,
* 'units' => 'lbs',
* 'label' => 'Foo',
* ),
* );
* @param string $notes
* Notes to add to the log.
* @param array $categories
* An array of categories to add to the log.
*
* @return \Log
* Returns a saved log entity.
*/
function farm_quantity_log_create($type, $name = '', $timestamp = REQUEST_TIME, $done = TRUE, $assets = array(), $measurements = array(), $notes = '', $categories = array()) {
// Create a new log entity.
$log = farm_log_create($type, $name, $timestamp, $done, $assets, $notes, $categories);
// Add quantity measurements.
farm_quantity_log_add_measurements($log, $measurements);
// Return the log.
return $log;
}
/**
* Helper function for adding quantity measurements to a log.
*
* @param \Log $log
* A log entity.
* @param array $measurements
* An array of measurements to add to the log. Example:
* $measurements = array(
* array(
* 'measure' => 'weight',
* 'value' => 100,
* 'units' => 'lbs',
* 'label' => 'Foo',
* ),
* );
*/
function farm_quantity_log_add_measurements($log, $measurements) {
// If the log is not valid, or the measurements are empty, bail.
if (empty($log->id) || empty($measurements)) {
return;
}
// Iterate through the measurements.
foreach ($measurements as $measurement) {
// Create a new quantity field_collection entity attached to the log.
$quantity = entity_create('field_collection_item', array(
'field_name' => 'field_farm_quantity',
));
$quantity
->setHostEntity('log', $log);
// Create an entity wrapper for the quantity.
$quantity_wrapper = entity_metadata_wrapper('field_collection_item', $quantity);
// Set the quantity measure, if available.
if (!empty($measurement['measure'])) {
$quantity_wrapper->field_farm_quantity_measure
->set($measurement['measure']);
}
// Set the quantity value, if available.
if (isset($measurement['value'])) {
$value_fraction = fraction_from_decimal($measurement['value']);
$quantity_wrapper->field_farm_quantity_value->numerator
->set($value_fraction
->getNumerator());
$quantity_wrapper->field_farm_quantity_value->denominator
->set($value_fraction
->getDenominator());
}
// Set the units, if available.
if (!empty($measurement['units'])) {
// Load/create units term.
$units_term = farm_term($measurement['units'], 'farm_quantity_units');
// Set the quantity units.
$quantity_wrapper->field_farm_quantity_units = $units_term;
}
// Set the label, if available.
if (!empty($measurement['label'])) {
$quantity_wrapper->field_farm_quantity_label
->set($measurement['label']);
}
// Save the quantity.
$quantity_wrapper
->save();
}
}
/**
* Helper function for updating the value of a quantity measurement on a log,
* based on its label.
*
* @param \Log $log
* A log entity.
* @param string $label
* The label of the quantity measurement that needs updating.
* @param string|float $value
* The new quantity measurement value.
*/
function farm_quantity_log_update_measurement_by_label($log, $label, $value) {
// Load the log entity metadata wrapper.
$log_wrapper = entity_metadata_wrapper('log', $log);
// If there are no quantities, bail.
if (empty($log_wrapper->field_farm_quantity)) {
return;
}
// Iterate over the quantities.
foreach ($log_wrapper->field_farm_quantity as $quantity) {
// If a label matches, update it.
if ($quantity->field_farm_quantity_label
->value() == $label) {
// Clear the old value.
$quantity->field_farm_quantity_value = array();
// Add the new value.
$value_fraction = fraction_from_decimal($value);
$quantity->field_farm_quantity_value->numerator
->set($value_fraction
->getNumerator());
$quantity->field_farm_quantity_value->denominator
->set($value_fraction
->getDenominator());
// Save the quantity.
$quantity
->save();
}
}
}
/**
* Helper function for deleting a quantity measurement from a log, based on its
* label.
*
* @param \Log $log
* A log entity.
* @param string $label
* The label of the quantity measurement that should be deleted.
*/
function farm_quantity_log_delete_measurement_by_label($log, $label) {
// Load the log entity metadata wrapper.
$log_wrapper = entity_metadata_wrapper('log', $log);
// If there are no quantities, bail.
if (empty($log_wrapper->field_farm_quantity)) {
return;
}
// Iterate over the quantities.
foreach ($log_wrapper->field_farm_quantity as $key => $quantity) {
// If the label matches, delete it.
if ($quantity->field_farm_quantity_label
->value() == $label) {
entity_delete('field_collection_item', $quantity->item_id
->value());
unset($log->field_farm_quantity[LANGUAGE_NONE][$key]);
log_save($log);
}
}
}
Functions
Name | Description |
---|---|
farm_quantity_log | Load all quantity logs that match certain criteria. |
farm_quantity_log_add_measurements | Helper function for adding quantity measurements to a log. |
farm_quantity_log_asset | Load logs for an asset with a given quantity measure and/or label. |
farm_quantity_log_asset_query | Build a query to find logs of an asset that defines a quantity. |
farm_quantity_log_create | Helper function for creating a farm quantity measurement log. |
farm_quantity_log_data | Extract quantity data from a log, with optional filters for measure/label. |
farm_quantity_log_delete_measurement_by_label | Helper function for deleting a quantity measurement from a log, based on its label. |
farm_quantity_log_query | Build a query to find logs that define quantity measurements. |
farm_quantity_log_query_add_filters | Helper function for adding joins and filters to a quantity log query. |
farm_quantity_log_update_measurement_by_label | Helper function for updating the value of a quantity measurement on a log, based on its label. |