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'), $container->get('database'), $container->get('group.membership') ); } /** * {@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; } /** * {@inheritdoc} */ public function getAssetsByLocation(array $locations): array { // First delegate to the parent function to get assets in the location. /** @var \Drupal\asset\Entity\AssetInterface[] $assets */ $assets = parent::getAssetsByLocation($locations); // Recursively load all group members and add them to the list of assets. $groups = array_filter($assets, function (AssetInterface $asset) { return $asset->bundle() === 'group'; }); $members = $this->groupMembership->getGroupMembers($groups, TRUE); $assets = array_merge($assets, $members); // Get location ids. $location_ids = array_map(function (AssetInterface $location) { return $location->id(); }, $locations); // 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 // 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)); }); // Return the assets. return $assets; } }