mirror of
https://github.com/farmOS/farmOS.git
synced 2024-02-23 11:37:38 +01:00
190 lines
5.9 KiB
Plaintext
190 lines
5.9 KiB
Plaintext
<?php
|
|
/**
|
|
* @file
|
|
* Code for the Farm Group feature.
|
|
*/
|
|
|
|
include_once 'farm_group.features.inc';
|
|
|
|
/**
|
|
* Implements hook_farm_ui_entities().
|
|
*/
|
|
function farm_group_farm_ui_entities() {
|
|
return array(
|
|
'farm_asset' => array(
|
|
'group' => array(
|
|
'label' => t('Group'),
|
|
'label_plural' => t('Groups'),
|
|
'view' => 'farm_groups',
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Load groups that an asset is a member of.
|
|
*
|
|
* @param FarmAsset $asset
|
|
* The farm_asset object to look 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 $done
|
|
* Whether or not to only show logs that are marked as "done".
|
|
* Defaults to TRUE.
|
|
*
|
|
* @return array
|
|
* Returns an array of groups that the asset is a member of.
|
|
*/
|
|
function farm_group_asset_membership(FarmAsset $asset, $time = REQUEST_TIME, $done = TRUE) {
|
|
$groups = array();
|
|
|
|
// Load the log using our helper function.
|
|
$log = farm_group_asset_latest_membership($asset, $time, $done);
|
|
|
|
// If no groups are specified, bail.
|
|
if (empty($log->field_farm_group[LANGUAGE_NONE])) {
|
|
return $groups;
|
|
}
|
|
|
|
// Iterate through the referenced groups and load them.
|
|
if (!empty($log->field_farm_group[LANGUAGE_NONE])) {
|
|
foreach ($log->field_farm_group[LANGUAGE_NONE] as $group_reference) {
|
|
if (!empty($group_reference['target_id'])) {
|
|
$group = farm_asset_load($group_reference['target_id']);
|
|
if (!empty($group)) {
|
|
$groups[] = $group;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return $groups;
|
|
}
|
|
|
|
/**
|
|
* Load an asset's latest log that defines a group membership.
|
|
*
|
|
* @param FarmAsset $asset
|
|
* The farm_asset object to look 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 $done
|
|
* Whether or not to only show logs that are marked as "done". Defaults to
|
|
* TRUE.
|
|
*
|
|
* @return Log|bool
|
|
* Returns a log entity. FALSE if something goes wrong.
|
|
*/
|
|
function farm_group_asset_latest_membership(FarmAsset $asset, $time = REQUEST_TIME, $done = TRUE) {
|
|
|
|
/**
|
|
* Please read the comments in farm_group_asset_membership_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.
|
|
*/
|
|
|
|
// 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 group membership log.
|
|
$query = farm_group_asset_membership_query($asset->id, $time, $done);
|
|
|
|
// Execute the query and gather the log id.
|
|
$result = $query->execute();
|
|
$log_id = $result->fetchField();
|
|
|
|
// If a log id exists, load and return it.
|
|
if (!empty($log_id)) {
|
|
return log_load($log_id);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
* Build a query to find group membership logs of a specific asset.
|
|
*
|
|
* @param int|string $asset_id
|
|
* The asset id to search for. This can either be a specific id, or a field
|
|
* alias string from another query (ie: 'mytable.assetid'). For an example
|
|
* of field alias string usage, see the Views relationship handler code in
|
|
* farm_group_handler_relationship_membership::query().
|
|
* @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 $done
|
|
* Whether or not to only show logs that are marked as "done". Defaults to
|
|
* TRUE.
|
|
* @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_group_asset_membership_query($asset_id, $time = REQUEST_TIME, $done = TRUE, $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, $single);
|
|
|
|
// Join in the log's "group" field, and filter to only include logs that have
|
|
// a "group" value defined.
|
|
$query->join('field_data_field_farm_group', 'ss_fdffg', "ss_fdffg.entity_type = 'log' AND ss_fdffg.entity_id = ss_log.id AND ss_fdffg.deleted = 0");
|
|
$query->where('ss_fdffg.field_farm_group_target_id IS NOT NULL');
|
|
|
|
// Add the log ID field.
|
|
$query->addField('ss_log', 'id');
|
|
|
|
// Return the query object.
|
|
return $query;
|
|
}
|
|
|
|
/**
|
|
* Recursively check for circular group membership.
|
|
*
|
|
* @param FarmAsset $group
|
|
* The group that the asset will be added to.
|
|
* @params FarmAsset $asset
|
|
* The asset being considered for membership in the group.
|
|
*
|
|
* @return bool
|
|
* Returns TRUE if a circular dependency would exist if the asset became a
|
|
* member of the group, FALSE otherwise.
|
|
*/
|
|
function farm_group_circular_membership(FarmAsset $group, FarmAsset $asset) {
|
|
|
|
// A group can't be inside itself. This is primarily how we will check for
|
|
// circular membership, along with recursively checking parent groups below.
|
|
if ($group->id == $asset->id) {
|
|
return TRUE;
|
|
}
|
|
|
|
// Check to see if the group is a member of other groups.
|
|
$parent_groups = farm_group_asset_membership($group);
|
|
|
|
// If no parent groups were found, no circular membership can exist.
|
|
if (empty($parent_groups)) {
|
|
return FALSE;
|
|
}
|
|
|
|
// Iterate through the parent groups and recurse into them to check if the
|
|
// new asset will create a circular membership anywhere down the line.
|
|
foreach ($parent_groups as $parent_group) {
|
|
if (farm_group_circular_membership($parent_group, $asset)) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
// Ok we're good! No circular memberships detected!
|
|
return FALSE;
|
|
}
|