- Модуль: mail
- Путь к файлу: ~/bitrix/modules/mail/lib/helper/mailbox/imap.php
- Класс: BitrixMailHelperMailboxImap
- Вызов: Imap::resyncDirInternal
protected function resyncDirInternal($dir, $numberForResync = false)
{
$meta = $this->client->select($dir->getPath(), $error);
if (false === $meta)
{
$this->warnings->add($this->client->getErrors()->toArray());
return false;
}
$uidtoken = $meta['uidvalidity'];
if ($meta['exists'] > 0)
{
if ($uidtoken > 0)
{
$result = $this->unregisterMessages(
array(
'=DIR_MD5' => md5($dir->getPath(true)),
' $uidtoken,
),
[
'info' => 'the directory has been deleted',
]
);
$countDeleted = $result ? $result->getCount() : 0;
$this->lastSyncResult['deletedMessages'] += $countDeleted;
}
}
else
{
if ($this->client->ensureEmpty($dir->getPath(), $error))
{
$result = $this->unregisterMessages(
array(
'=DIR_MD5' => md5($dir->getPath(true)),
),
[
'info' => 'all messages in the directory have been deleted ',
]
);
$countDeleted = $result ? $result->getCount() : 0;
$this->lastSyncResult['deletedMessages'] += $countDeleted;
}
return;
}
$fetcher = function ($range) use ($dir)
{
$messages = $this->client->fetch(false, $dir->getPath(), $range, '(UID FLAGS)', $error);
if (empty($messages))
{
if (false === $messages)
{
$this->warnings->add($this->client->getErrors()->toArray());
}
else
{
// @TODO: log
}
return false;
}
krsort($messages);
return $messages;
};
$messagesNumberInTheMailService = $meta['exists'];
$messages = $fetcher(($messagesNumberInTheMailService > 10000 || $numberForResync !== false) ? sprintf('1,%u', $messagesNumberInTheMailService) : '1:*');
if (empty($messages))
{
return (false === $messages ? false : null);
}
//interval of messages in the directory
$range = array(
reset($messages)['UID'],
end($messages)['UID'],
);
sort($range);
if($range[0]===$range[1] and $messagesNumberInTheMailService > 1)
{
return false;
}
//deleting non-existent messages in the service ( not included in the message interval on the service )
$result = $this->unregisterMessages(
array(
'=DIR_MD5' => md5($dir->getPath(true)),
'>MSG_UID' => 0,
array(
'LOGIC' => 'OR',
' $range[0],
'>MSG_UID' => $range[1],
),
),
[
'info' => 'optimized deletion of non-existent messages',
]
);
$countDeleted = $result ? $result->getCount() : 0;
$this->lastSyncResult['deletedMessages'] += $countDeleted;
//resynchronizing a certain number of messages
if($numberForResync !== false)
{
$range1 = $meta['exists'];
$range0 = max($range1 - ($numberForResync - 1), 1);
$messages = $fetcher(sprintf('%u:%u', $range0, $range1));
if (empty($messages))
{
return;
}
$this->resyncMessages($dir->getPath(true), $uidtoken, $messages);
return;
}
if (!($meta['exists'] > 10000))
{
$this->resyncMessages($dir->getPath(true), $uidtoken, $messages);
return;
}
$range1 = $meta['exists'];
while ($range1 > 0)
{
$rangeSize = $range1 > 10000 ? 8000 : $range1;
$range0 = max($range1 - $rangeSize, 1);
$messages = $fetcher(sprintf('%u:%u', $range0, $range1));
if (empty($messages))
{
return;
}
$this->resyncMessages($dir->getPath(true), $uidtoken, $messages);
if ($this->isTimeQuotaExceeded())
{
return;
}
$range1 -= $rangeSize;
}
}