• Модуль: disk
  • Путь к файлу: ~/bitrix/modules/disk/lib/rightsmanager.php
  • Класс: BitrixDiskRightsSetter
  • Вызов: RightsSetter::appendOneNegative
private function appendOneNegative(array $right, $hadOppositeRight = false)
{
	$isValidNegaviteRight = $this->validateNegaviteRight($right);
	if(!$isValidNegaviteRight && !$hadOppositeRight)
	{
		$this->errorCollection->addOne(new Error('Invalid negative right'));
		return false;
	}

	//we don't have to add negative right. We must only delete old simple rights. condition($hadOppositeRight && !$isValidNegaviteRight)
	if($isValidNegaviteRight)
	{
		//May we have to add record to b_disk_right in final.
		$right['OBJECT_ID'] = $this->object->getId();
		$result = RightTable::add($right);
		if (!$result->isSuccess())
		{
			$this->errorCollection->addFromResult($result);

			return false;
		}
	}

	$rightsManager = Driver::getInstance()->getRightsManager();
	if(!$rightsManager->containsOperationInTask($rightsManager::OP_READ, $right['TASK_ID']))
	{
		return true;
	}

	if(!$this->hasAlreadySimpleRight($right['ACCESS_CODE']))
	{
		//below we already have negative rights, which deleted simple rights.
		return true;
	}
	//need to delete simple rights from descendants
	$conflictRightsInSubTree = $this->getConflictRightsInSubTree($right['ACCESS_CODE'], $right['TASK_ID']);
	$accessCode = $this->sqlHelper->forSql($right['ACCESS_CODE']);
	if(empty($conflictRightsInSubTree))
	{
		//we have to destroy simple right from all descendants and from current OBJECT_ID
		$this->connection->queryExecute("
			DELETE simple FROM b_disk_simple_right simple
				INNER JOIN b_disk_object_path p ON p.OBJECT_ID = simple.OBJECT_ID
			WHERE p.PARENT_ID = {$this->object->getId()} AND simple.ACCESS_CODE = '{$accessCode}'
		");
	}
	else
	{
		$objectIds = array();
		foreach($conflictRightsInSubTree as $conflictRight)
		{
			$objectIds[] = $conflictRight['OBJECT_ID'];
		}
		unset($conflictRight);
		//we have to destroy simple right from all descendants and from current OBJECT_ID without nodes with conflict rights in path.
		$this->connection->queryExecute("
			DELETE simple FROM b_disk_simple_right simple
				INNER JOIN b_disk_object_path p ON p.OBJECT_ID = simple.OBJECT_ID
			WHERE
				p.PARENT_ID = {$this->object->getId()} AND simple.ACCESS_CODE = '{$accessCode}' AND
				NOT EXISTS(
					SELECT 'x' FROM b_disk_object_path pp
						WHERE pp.OBJECT_ID = p.OBJECT_ID AND
						pp.PARENT_ID IN (" . implode(',', $objectIds)  . ") )
		");
	}

	return true;
}