- Модуль: 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;
}