public 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->add(array(new Error(Loc::getMessage('DISK_SHARING_MODEL_ERROR_EMPTY_REAL_OBJECT'), self::ERROR_EMPTY_REAL_OBJECT))); return null; } /** @var \Bitrix\Disk\BaseObject $objectToSharing */ $objectToSharing = $data['REAL_OBJECT']; //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 ProxyType\User) { $ownerUserId = $objectToSharing->getStorage()->getEntityId(); } $rightManager = Driver::getInstance()->getRightsManager(); /** @var Sharing[] $successSharingByEntity */ $successSharingByEntity = array(); foreach ($entitiesToTask as $entity => $taskName) { list($type, ) = self::parseEntityValue($entity); if (!$type) { continue; } $dataToInsert['TO_ENTITY'] = $entity; $dataToInsert['TYPE'] = $type; $dataToInsert['TASK_NAME'] = $taskName; if ($type == SharingTable::TYPE_TO_DEPARTMENT) { $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; } $sharingDomain = $rightManager->getSharingDomain($sharingModel->getId()); /** @var \Bitrix\Disk\Sharing $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); return $successSharingByEntity; }