- Модуль: mail
- Путь к файлу: ~/bitrix/modules/mail/lib/helper/mailbox/imap.php
- Класс: BitrixMailHelperMailboxImap
- Вызов: Imap::syncDirInternal
protected function syncDirInternal($dir)
{
$messagesSynced = 0;
$meta = $this->client->select($dir->getPath(), $error);
if (false === $meta)
{
$this->warnings->add($this->client->getErrors()->toArray());
if ($this->client->isExistsDir($dir->getPath(), $error) === false)
{
$this->getDirsHelper()->removeDirsLikePath([$dir]);
}
return false;
}
$this->getDirsHelper()->updateMessageCount($dir->getId(), $meta['exists']);
$intervalSynchronizationAttempts = 0;
while ($range = $this->getSyncRange($dir->getPath(), $uidtoken, $intervalSynchronizationAttempts))
{
$reverse = $range[0] > $range[1];
sort($range);
$messages = $this->client->fetch(
true,
$dir->getPath(),
join(':', $range),
'(UID FLAGS INTERNALDATE RFC822.SIZE BODYSTRUCTURE BODY.PEEK[HEADER])',
$error
);
$fetchErrors=$this->client->getErrors();
$errorReceivingMessages = $fetchErrors->getErrorByCode(210) !== null;
$failureDueToDataVolume = $fetchErrors->getErrorByCode(104) !== null;
if (empty($messages))
{
if (false === $messages)
{
if($errorReceivingMessages && !$failureDueToDataVolume)
{
/*
Skip the intervals where all the messages were broken
*/
return $messagesSynced;
}
elseif($failureDueToDataVolume && $intervalSynchronizationAttempts < count(self::MAXIMUM_SYNCHRONIZATION_LENGTHS_OF_INTERVALS) - 1 )
{
$intervalSynchronizationAttempts++;
continue;
/*
Trying to resynchronize by reducing the interval
*/
}
else
{
/*
Fatal errors in which we cannot perform synchronization
*/
$this->warnings->add($fetchErrors->toArray());
return false;
}
}
break;
}
else
{
$intervalSynchronizationAttempts = 0;
}
$reverse ? krsort($messages) : ksort($messages);
$this->parseHeaders($messages);
$this->blacklistMessages($dir->getPath(), $messages);
$this->removeExistingMessagesFromSynchronizationList($dir->getPath(), $uidtoken, $messages);
foreach ($messages as &$message)
{
$this->fillMessageFields($message, $dir->getPath(), $uidtoken);
}
$this->linkWithExistingMessages($messages);
$hashesMap = [];
//To display new messages(grid reload) until synchronization is complete
$numberOfMessagesInABatch = 1;
$numberLeftToFillTheBatch = $numberOfMessagesInABatch;
foreach ($messages as $item)
{
$isOutgoing = false;
if(empty($item['__replaces']))
{
$outgoingMessageId = $this->selectOutgoingMessageIdFromHeader($item);
if($outgoingMessageId)
{
$item['__replaces'] = $outgoingMessageId;
$isOutgoing = true;
}
}
if ($this->syncMessage($dir->getPath(), $item, $hashesMap, false, $isOutgoing))
{
$this->lastSyncResult['newMessageId'] = end($hashesMap);
$messagesSynced++;
$numberLeftToFillTheBatch--;
if($numberLeftToFillTheBatch === 0 and MainLoader::includeModule('pull'))
{
$numberOfMessagesInABatch *= 2;
$numberLeftToFillTheBatch = $numberOfMessagesInABatch;
CPullWatch::addToStack(
'mail_mailbox_' . $this->mailbox['ID'],
[
'params' => [
'dir' => $dir->getPath(),
'mailboxId' => $this->mailbox['ID'],
],
'module_id' => 'mail',
'command' => 'new_message_is_synchronized',
]
);
BitrixPullEvent::send();
}
}
if ($this->isTimeQuotaExceeded())
{
break 2;
}
}
}
if (false === $range)
{
$this->warnings->add($this->client->getErrors()->toArray());
return false;
}
return $messagesSynced;
}