2021-03-01 16:40:53 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Drupal\farm_group;
|
|
|
|
|
2021-03-01 17:15:28 +01:00
|
|
|
use Drupal\asset\Entity\AssetInterface;
|
2021-03-05 00:24:01 +01:00
|
|
|
use Drupal\Component\Datetime\TimeInterface;
|
2021-06-03 13:24:18 +02:00
|
|
|
use Drupal\Core\Database\Connection;
|
2021-03-05 00:24:01 +01:00
|
|
|
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
2021-03-01 16:40:53 +01:00
|
|
|
use Drupal\farm_location\AssetLocation;
|
|
|
|
use Drupal\farm_location\AssetLocationInterface;
|
2021-03-05 00:24:01 +01:00
|
|
|
use Drupal\farm_location\LogLocationInterface;
|
|
|
|
use Drupal\farm_log\LogQueryFactoryInterface;
|
2021-03-01 17:15:28 +01:00
|
|
|
use Drupal\log\Entity\LogInterface;
|
2021-03-05 00:24:01 +01:00
|
|
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
2021-03-01 16:40:53 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Asset location logic, accounting for group membership.
|
|
|
|
*/
|
|
|
|
class GroupAssetLocation extends AssetLocation implements AssetLocationInterface {
|
|
|
|
|
2021-03-05 00:24:01 +01:00
|
|
|
/**
|
|
|
|
* Group membership service.
|
|
|
|
*
|
|
|
|
* @var \Drupal\farm_group\GroupMembershipInterface
|
|
|
|
*/
|
|
|
|
protected GroupMembershipInterface $groupMembership;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Class constructor.
|
|
|
|
*
|
|
|
|
* @param \Drupal\farm_location\LogLocationInterface $log_location
|
|
|
|
* Log location service.
|
|
|
|
* @param \Drupal\farm_log\LogQueryFactoryInterface $log_query_factory
|
|
|
|
* Log query factory.
|
|
|
|
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
|
|
|
|
* Entity type manager.
|
|
|
|
* @param \Drupal\Component\Datetime\TimeInterface $time
|
|
|
|
* The time service.
|
2021-06-03 13:24:18 +02:00
|
|
|
* @param \Drupal\Core\Database\Connection $database
|
|
|
|
* The database service.
|
2021-03-05 00:24:01 +01:00
|
|
|
* @param \Drupal\farm_group\GroupMembershipInterface $group_membership
|
|
|
|
* The group membership service.
|
|
|
|
*/
|
2021-06-03 13:24:18 +02:00
|
|
|
public function __construct(LogLocationInterface $log_location, LogQueryFactoryInterface $log_query_factory, EntityTypeManagerInterface $entity_type_manager, TimeInterface $time, Connection $database, GroupMembershipInterface $group_membership) {
|
|
|
|
parent::__construct($log_location, $log_query_factory, $entity_type_manager, $time, $database);
|
2021-03-05 00:24:01 +01:00
|
|
|
$this->groupMembership = $group_membership;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* {@inheritdoc}
|
|
|
|
*/
|
|
|
|
public static function create(ContainerInterface $container) {
|
|
|
|
return new static(
|
|
|
|
$container->get('log.location'),
|
|
|
|
$container->get('farm.log_query'),
|
|
|
|
$container->get('entity_type.manager'),
|
|
|
|
$container->get('datetime.time'),
|
2021-06-03 13:24:18 +02:00
|
|
|
$container->get('database'),
|
2021-03-05 00:24:01 +01:00
|
|
|
$container->get('group.membership')
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-03-01 17:15:28 +01:00
|
|
|
/**
|
|
|
|
* {@inheritdoc}
|
|
|
|
*/
|
|
|
|
public function getMovementLog(AssetInterface $asset): ?LogInterface {
|
|
|
|
|
|
|
|
// Delegate to the parent service to get the latest movement log that
|
|
|
|
// references this asset.
|
|
|
|
$latest_movement = parent::getMovementLog($asset);
|
|
|
|
|
|
|
|
// Remember the latest movement id and timestamp.
|
|
|
|
$latest_id = 0;
|
|
|
|
$latest_timestamp = 0;
|
|
|
|
if (!empty($latest_movement)) {
|
|
|
|
$latest_id = $latest_movement->id();
|
|
|
|
$latest_timestamp = $latest_movement->get('timestamp')->value;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the groups that this asset is assigned to.
|
|
|
|
$groups = $this->groupMembership->getGroup($asset);
|
|
|
|
|
|
|
|
// If there are groups, iterate through them.
|
|
|
|
if (!empty($groups)) {
|
|
|
|
foreach ($groups as $group) {
|
|
|
|
|
|
|
|
// Get the latest movement log that references the group.
|
|
|
|
$group_movement = parent::getMovementLog($group);
|
|
|
|
|
|
|
|
// If the group doesn't have a movement, skip it.
|
|
|
|
if (empty($group_movement)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the group's movement is the latest, replace the latest movement.
|
|
|
|
$group_movement_id = $group_movement->id();
|
|
|
|
$group_movement_timestamp = $group_movement->get('timestamp')->value;
|
|
|
|
if (($group_movement_id > $latest_id) && ($group_movement_timestamp >= $latest_timestamp)) {
|
|
|
|
$latest_movement = $group_movement;
|
|
|
|
$latest_id = $group_movement_id;
|
|
|
|
$latest_timestamp = $group_movement_timestamp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return the latest movement log.
|
|
|
|
return $latest_movement;
|
|
|
|
}
|
|
|
|
|
2021-06-03 13:24:18 +02:00
|
|
|
/**
|
|
|
|
* {@inheritdoc}
|
|
|
|
*/
|
2021-10-27 18:03:53 +02:00
|
|
|
public function getAssetsByLocation(array $locations): array {
|
2021-06-03 13:24:18 +02:00
|
|
|
|
|
|
|
// First delegate to the parent function to get assets in the location.
|
|
|
|
/** @var \Drupal\asset\Entity\AssetInterface[] $assets */
|
2021-10-27 18:03:53 +02:00
|
|
|
$assets = parent::getAssetsByLocation($locations);
|
2021-06-03 13:24:18 +02:00
|
|
|
|
|
|
|
// Recursively load all group members and add them to the list of assets.
|
2021-10-27 01:52:13 +02:00
|
|
|
$groups = array_filter($assets, function (AssetInterface $asset) {
|
|
|
|
return $asset->bundle() === 'group';
|
|
|
|
});
|
|
|
|
$members = $this->groupMembership->getGroupMembers($groups, TRUE);
|
2021-06-03 13:24:18 +02:00
|
|
|
$assets = array_merge($assets, $members);
|
|
|
|
|
2021-10-27 18:03:53 +02:00
|
|
|
// Get location ids.
|
|
|
|
$location_ids = array_map(function (AssetInterface $location) {
|
|
|
|
return $location->id();
|
|
|
|
}, $locations);
|
|
|
|
|
2021-06-03 13:24:18 +02:00
|
|
|
// It is possible for a group member asset to be in a different location
|
|
|
|
// than the group, if it has a movement log that is more recent than the
|
|
|
|
// group's. So iterate through all the assets and remove any that are not in
|
2021-10-27 18:03:53 +02:00
|
|
|
// one of the specified locations. The asset may be in multiple locations
|
|
|
|
// (including this one), so we only want to remove it if none of its
|
|
|
|
// locations match.
|
|
|
|
$assets = array_filter($assets, function (AssetInterface $asset) use ($location_ids) {
|
|
|
|
|
|
|
|
// Get asset location ids.
|
|
|
|
$asset_location_ids = array_map(function (AssetInterface $location) {
|
|
|
|
return $location->id();
|
|
|
|
}, $this->getLocation($asset));
|
|
|
|
|
|
|
|
// Only include the asset if it is in one of the specified locations.
|
|
|
|
return !empty(array_intersect($location_ids, $asset_location_ids));
|
|
|
|
});
|
2021-06-03 13:24:18 +02:00
|
|
|
|
|
|
|
// Return the assets.
|
|
|
|
return $assets;
|
|
|
|
}
|
|
|
|
|
2021-03-01 16:40:53 +01:00
|
|
|
}
|