• Модуль: disk
  • Путь к файлу: ~/bitrix/modules/disk/lib/bitrix24disk/subscribermanager.php
  • Класс: BitrixDiskBitrix24DiskSubscriberManager
  • Вызов: SubscriberManager::collectSubscribersGeneralWay
protected function collectSubscribersGeneralWay(BaseObject $object, $direction)
{
	set_time_limit(0);

	if (!in_array($direction, [self::DIRECTION_PARENTS, self::DIRECTION_SUBTREE], true))
	{
		throw new ArgumentException('Invalid argument value for', 'direction');
	}

	$maxInnerJoinDepth = 12;
	$currentDepth = 0;
	$emptySelect = false;
	$connection = Application::getConnection();
	$objectId = (int)$object->getId();
	$sharingStatus = Sharing::STATUS_IS_DECLINED;

	$ownerStorageIds = [];
	$subscribers = [];
	$where = "
		WHERE
			path." . ($direction === self::DIRECTION_PARENTS? 'OBJECT_ID' : 'PARENT_ID') . " = {$objectId} AND sharing.STATUS <> {$sharingStatus}							
	";

	$sliceHashes = [];
	while ($currentDepth < $maxInnerJoinDepth && !$emptySelect)
	{
		$aliasTable = "sharing" . ($currentDepth-1 >= 0 ? $currentDepth-1: '');
		$query = "
			SELECT DISTINCT {$aliasTable}.ID, {$aliasTable}.TO_ENTITY, {$aliasTable}.LINK_STORAGE_ID, {$aliasTable}.REAL_STORAGE_ID 
			FROM b_disk_object_path path
				INNER JOIN b_disk_sharing sharing ON sharing.REAL_OBJECT_ID = path." . ($direction === self::DIRECTION_PARENTS? 'PARENT_ID' : 'OBJECT_ID') . "
		";

		$emptySelect = true;
		$finalQuery = $query;
		for ($i = 0; $i < $currentDepth; $i++)
		{
			$prevI = ($i-1 >= 0)? ($i-1): '';
			$finalQuery .= " 
				 INNER JOIN b_disk_object_path path{$i} ON path{$i}.OBJECT_ID = sharing{$prevI}.LINK_OBJECT_ID
				 INNER JOIN b_disk_sharing sharing{$i} ON sharing{$i}.REAL_OBJECT_ID = path{$i}.PARENT_ID
			";
		}

		$finalQuery = $finalQuery . $where . " ORDER BY {$aliasTable}.ID";

		$ids = [];
		foreach ($connection->query($finalQuery) as $row)
		{
			$ids[] = $row['ID'];

			$emptySelect = false;
			[$type, $id] = Sharing::parseEntityValue($row['TO_ENTITY']);
			if($type === Sharing::TYPE_TO_USER && $row['LINK_STORAGE_ID'])
			{
				$subscribers[$row['LINK_STORAGE_ID']] = $id;
			}

			$ownerStorageIds[$row['REAL_STORAGE_ID']] = $row['REAL_STORAGE_ID'];
		}

		$currentHash = md5(implode('|', $ids));
		if (in_array($currentHash, $sliceHashes, true))
		{
			//it's cycle! recursion!

			break;
		}
		$sliceHashes[$currentDepth] = $currentHash;

		$currentDepth++;
	}

	$ownerStorageIds[$object->getStorageId()] = $object->getStorageId();

	foreach ($this->getSubscribresByStorages($ownerStorageIds) as $storageId => $userId)
	{
		$subscribers[$storageId] = $userId;
	}

	return $subscribers;
}