• Модуль: disk
  • Путь к файлу: ~/bitrix/modules/disk/lib/bitrix24disk/legacy/newdiskstorage.php
  • Класс: BitrixDiskBitrix24DiskLegacyNewDiskStorage
  • Вызов: NewDiskStorage::snapshotFromPersonalStorage
private function snapshotFromPersonalStorage(FixedArray $items, PageState $pageState, $internalVersion, $pageSize = self::SNAPSHOT_PAGE_SIZE)
{
	if($pageState->getStep() !== $pageState::STEP_PERSONAL)
	{
		return;
	}

	$hasNextPage = false;
	$nextCursor = $nextId = null;
	$expectedFirstId = $pageState->getNextId();
	$cursor = $pageState->getCursor()?: $internalVersion;

	$query = new InternalsEntityQuery(ObjectTable::getEntity());
	$query->setSelect(['ID']);

	if(!$this->checkOpportunityToSkipRights())
	{
		$securityContext = $this->storage->getSecurityContext($this->userId);
		$query
			->addFilter('=RIGHTS_CHECK', true)
			->registerRuntimeField(
				'RIGHTS_CHECK',
				new ExpressionField(
					'RIGHTS_CHECK',
					'CASE WHEN ' . $securityContext->getSqlExpressionForList('%1$s', '%2$s') . ' THEN 1 ELSE 0 END',
					array('ID', 'CREATED_BY')
				)
			)
		;
	}

	if($cursor > 0)
	{
		$query->addFilter('>=SYNC_UPDATE_TIME', DateTime::createFromTimestamp($cursor));
	}

	$query
		->addFilter('STORAGE_ID', $this->storage->getId())
		->addFilter('DELETED_TYPE', ObjectTable::DELETED_TYPE_NONE)
		->addOrder('SYNC_UPDATE_TIME')
		->addOrder('ID')
		->setLimit($pageSize + 1)
	;

	$offset = $pageState->getOffset();
	if ($cursor && $offset)
	{
		//we want to skip values which were on previous page.
		$query->setOffset($offset);
	}

	$objectIds = [];
	foreach ($query->exec() as $item)
	{
		$objectIds[] = $item['ID'];
	}

	$fetchedItems = [];
	if ($objectIds)
	{
		$query = new InternalsEntityQuery(ObjectTable::getEntity());
		$query
			->setSelect($this->getSelectableColumnsForObject())
			->addFilter('@ID', $objectIds)
			->addOrder('SYNC_UPDATE_TIME')
			->addOrder('ID')
		;
		if ($this->isEnabledObjectLock)
		{
			$query->addSelect('LOCK.*', self::LOCK_PREFIX_IN_SELECT);
		}

		$fetchedItems = $query->exec()->fetchAll();
	}

	$count = 0;
	foreach($fetchedItems as $item)
	{
		if($count === 0)
		{
			if($expectedFirstId !== null && $item['ID'] != $expectedFirstId)
			{
				throw new UnexpectedNextIdException("{$expectedFirstId} vs {$item['ID']}");
			}

			$this->loadTree();
			$this->loadSharedData();
		}

		$count++;
		if($count > $pageSize)
		{
			$nextCursor = $item['SYNC_UPDATE_TIME']->getTimestamp();
			$nextId = $item['ID'];
			$hasNextPage = true;

			break;
		}

		$formattedItem = $this->formatObjectRowToResponse($item);
		if(!$formattedItem || $formattedItem['path'] === '/')
		{
			$items->push(array(
				'version' => (string)$this->generateTimestamp($item['SYNC_UPDATE_TIME']->getTimestamp()),
			));
			//but we can have null on the page in snapshots. It's necessary for correct page navigation.
			continue;
		}

		$items->push($formattedItem);
	}

	$pageState->reset();
	if($hasNextPage)
	{
		$toSkipOnNextStep = 0;
		if($cursor == $nextCursor)
		{
			$toSkipOnNextStep += $offset;
		}

		$toSkipOnNextStep += $this->countIdsWithSameSyncDate($items, $this->convertToExternalVersion($nextCursor));
		if($toSkipOnNextStep)
		{
			$pageState->setOffset($toSkipOnNextStep);
		}

		$pageState
			->setStep($pageState::STEP_PERSONAL)
			->setCursor($nextCursor)
			->setNextId($nextId)
		;
	}
}