- Модуль: disk
- Путь к файлу: ~/bitrix/modules/disk/lib/bitrix24disk/legacy/newdiskstorage.php
- Класс: BitrixDiskBitrix24DiskLegacyNewDiskStorage
- Вызов: NewDiskStorage::snapshotFromLink
private function snapshotFromLink(TreeNode $link, FixedArray $items, PageState $pageState, $internalVersion, $pageSize = self::SNAPSHOT_PAGE_SIZE)
{
$hasNextPage = false;
$nextCursor = $nextId = null;
$expectedFirstId = empty($dataByStep['lid'])? null : $dataByStep['lid'];
$securityContext = $this->storage->getSecurityContext($this->userId);
$query = new InternalsEntityQuery(ObjectTable::getEntity());
$query
->setSelect(['ID'])
->addFilter('PATH_CHILD.PARENT_ID', $link->realObjectId)
->addFilter('DELETED_TYPE', ObjectTable::DELETED_TYPE_NONE)
->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')
)
)
->addOrder('SYNC_UPDATE_TIME')
->addOrder('ID')
// ->addOrder('PATH_CHILD.OBJECT_ID')
->setLimit($pageSize + 1)
;
$cursor = $pageState->getCursor();
if (
!$cursor &&
$internalVersion > 0 &&
$this->compareVersion(
$this->convertToExternalVersion($link->createDate->getTimestamp()),
$this->convertToExternalVersion($internalVersion)
) < 0
)
{
$cursor = $internalVersion;
}
if($cursor > 0)
{
$query->addFilter('>=SYNC_UPDATE_TIME', DateTime::createFromTimestamp($cursor));
}
$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'];
if ($expectedFirstId !== null && $item['ID'] != $expectedFirstId)
{
throw new UnexpectedNextIdException("{$expectedFirstId} vs {$item['ID']}");
}
}
$fetchedItems = [];
if ($objectIds)
{
$query = new InternalsEntityQuery(ObjectTable::getEntity());
$query
->setSelect($this->getSelectableColumnsForObject())
->addFilter('@ID', $objectIds)
->addOrder('SYNC_UPDATE_TIME')
->addOrder('ID')
->setLimit($pageSize + 1)
;
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'] === '/' ||
//this is root of symlink. We don't have to show it. We show only symlink.
($link->realObjectId == $item['ID'] && $link->realObjectId == $item['REAL_OBJECT_ID'])
)
{
$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_SYMLINKS)
->setNextId($link->id)
->setCursor($nextCursor)
->setDataByStep(array(
'lid' => $nextId
))
;
}
}