• Модуль: disk
  • Путь к файлу: ~/bitrix/modules/disk/lib/sharing.php
  • Класс: BitrixDiskSharing
  • Вызов: Sharing::addToManyEntities
static function addToManyEntities(array $data, array $entitiesToTask, ErrorCollection $errorCollection)
{
	self::checkRequiredInputParams($data, array('FROM_ENTITY', 'CREATED_BY'));

	if(isset($data['REAL_OBJECT']) && $data['REAL_OBJECT'] instanceof BaseObject)
	{
		/** @noinspection PhpUndefinedMethodInspection */
		$data['REAL_OBJECT_ID'] = $data['REAL_OBJECT']->getId();
	}
	elseif(isset($data['REAL_OBJECT_ID']))
	{
		$data['REAL_OBJECT'] = BaseObject::loadById($data['REAL_OBJECT_ID']);
	}
	else
	{
		$errorCollection->addOne(
			new Error(Loc::getMessage('DISK_SHARING_MODEL_ERROR_EMPTY_REAL_OBJECT'), self::ERROR_EMPTY_REAL_OBJECT)
		);
		return null;
	}
	/** @var BitrixDiskBaseObject $objectToSharing */
	$objectToSharing = $data['REAL_OBJECT'];

	$entitiesToTask = static::deletePossibleCycleFromEntities($objectToSharing, $entitiesToTask);

	//resolve to last real object. In table we write only real (not link) id.
	$objectToSharing = $objectToSharing->getRealObject();
	$data['REAL_OBJECT_ID'] = $objectToSharing->getId();
	$data['REAL_STORAGE_ID'] = $objectToSharing->getStorageId();

	$dataToInsert = $data;
	unset($dataToInsert['REAL_OBJECT']);

	//we don't have to connect object, which already exists in same storage
	$ownerUserId = null;
	if($objectToSharing->getStorage()->getProxyType() instanceof ProxyTypeUser)
	{
		$ownerUserId = $objectToSharing->getStorage()->getEntityId();
	}

	$rightManager = Driver::getInstance()->getRightsManager();
	/** @var Sharing[] $successSharingByEntity */
	$successSharingByEntity = array();
	foreach ($entitiesToTask as $entity => $taskName)
	{
		[$type, $id] = self::parseEntityValue($entity);
		if(!$type)
		{
			continue;
		}

		if ($type == SharingTable::TYPE_TO_USER && $id == $ownerUserId)
		{
			continue;
		}

		$dataToInsert['TO_ENTITY'] = $entity;
		$dataToInsert['TYPE'] = $type;
		$dataToInsert['TASK_NAME'] = $taskName;
		if($type == SharingTable::TYPE_TO_DEPARTMENT || $type == SharingTable::TYPE_TO_CHAT)
		{
			$dataToInsert['STATUS'] = SharingTable::STATUS_IS_APPROVED;
		}

		$sharingModel = parent::add($dataToInsert, $errorCollection);
		if(!$sharingModel)
		{
			continue;
		}

		$successSharingByEntity[$entity] = $sharingModel->setAttributes(array('REAL_OBJECT' => $objectToSharing));
		if($type == SharingTable::TYPE_TO_DEPARTMENT && Loader::includeModule('socialnetwork'))
		{
			unset($dataToInsert['STATUS']);
			//todo expand access code DR to list of users. And for each user of list create Sharing
			$dataToInsertChild = $dataToInsert;
			$dataToInsertChild['PARENT_ID'] = $sharingModel->getId();
			$dataToInsertChild['TYPE'] = SharingTable::TYPE_TO_USER;

			foreach(CSocNetLogDestination::getDestinationUsers(array($entity)) as $userId)
			{
				if($ownerUserId == $userId)
				{
					continue;
				}

				$dataToInsertChild['TO_ENTITY'] = self::CODE_USER . $userId;

				$sharingModel = parent::add($dataToInsertChild, $errorCollection);
				if(!$sharingModel)
				{
					continue;
				}
				//above we can already added sharing to this entity (user) and we should not overwrite that. DR-sharing has lower priority than another.
				if(!isset($successSharingByEntity[$dataToInsertChild['TO_ENTITY']]))
				{
					$successSharingByEntity[$dataToInsertChild['TO_ENTITY']] = $sharingModel->setAttributes(array('REAL_OBJECT' => $objectToSharing,));
				}
			}
			unset($userId);
		}
		elseif($type == SharingTable::TYPE_TO_GROUP)
		{
			//if sharing to socnet group, we should approve invite at once, because it's not personal invite.
			$sharingModel->approve();
		}

	}
	unset($entity, $dataToInsert);

	$forwardTaskId = !empty($data['CAN_FORWARD'])? $rightManager->getTaskIdByName($rightManager::OP_SHARING) : null;

	$newRights = array();
	foreach ($successSharingByEntity as $entity => $sharingModel)
	{
		if($sharingModel->isToDepartmentChild())
		{
			continue;
		}
		if($sharingModel->isToGroup())
		{
			$entity .= '_K'; //members of group.
		}

		$sharingDomain = $rightManager->getSharingDomain($sharingModel->getId());
		/** @var BitrixDiskSharing $sharingModel */
		$newRights[] = array(
			'ACCESS_CODE' => $entity,
			'TASK_ID' => $rightManager->getTaskIdByName($sharingModel->getTaskName()),
			'DOMAIN' => $sharingDomain,
		);
		if($forwardTaskId)
		{
			$newRights[] = array(
				'ACCESS_CODE' => $entity,
				'TASK_ID' => $forwardTaskId,
				'DOMAIN' => $sharingDomain,
			);
		}
	}
	unset($entity);
	$rightManager->append($objectToSharing, $newRights);

	self::processConnectAndNotify($successSharingByEntity, $objectToSharing);
	self::cleanCache($successSharingByEntity);

	return $successSharingByEntity;
}