• Модуль: disk
  • Путь к файлу: ~/bitrix/modules/disk/lib/rightsmanager.php
  • Класс: BitrixDiskSimpleRightBuilder
  • Вызов: SimpleRightBuilder::workWithNegativeNodes
private function workWithNegativeNodes()
{
	$negativeNodes = $this->connection->query("
		SELECT
			r.ACCESS_CODE, r.TASK_ID,
			r.OBJECT_ID, p.DEPTH_LEVEL
		FROM b_disk_right r
			INNER JOIN b_disk_object_path p ON p.OBJECT_ID = r.OBJECT_ID
		WHERE
			p.PARENT_ID = {$this->objectId} AND r.NEGATIVE = 1
	")->fetchAll();

	$rightsManager = Driver::getInstance()->getRightsManager();
	Collection::sortByColumn($negativeNodes, array('DEPTH_LEVEL' => SORT_ASC));
	foreach($negativeNodes as $negativeNode)
	{
		$nodeObject = BaseObject::buildFromArray(array(
			'ID' => $negativeNode['OBJECT_ID'],
			'TYPE' => ObjectTable::TYPE_FOLDER,
		));

		$runClean = true;
		foreach($rightsManager->getAllListNormalizeRights($nodeObject) as $right)
		{
			if($right['ACCESS_CODE'] !== $negativeNode['ACCESS_CODE'])
			{
				continue;
			}
			//the right goes from parent
			if(
				!empty($right['NEGATIVE']) &&
				$right['OBJECT_ID'] != $negativeNode['OBJECT_ID'] &&
				$right['TASK_ID'] == $negativeNode['TASK_ID']
			)
			{
				$runClean = false;
				break;
			}
			if(!empty($right['NEGATIVE']))
			{
				continue;
			}

			if($rightsManager->containsOperationInTask($rightsManager::OP_READ, $right['TASK_ID']))
			{
				$runClean = false;
				break;
			}
		}
		unset($right);

		if(!$runClean)
		{
			//the node and all sub-elements inherit OP_READ from another positive right.
			continue;
		}

		$this->deleteSimpleRightFromSubTree($negativeNode['OBJECT_ID'], $negativeNode['ACCESS_CODE']);
	}
	unset($negativeNode);

	return $this;
}