• Модуль: mail
  • Путь к файлу: ~/bitrix/modules/mail/lib/helper/mailbox.php
  • Класс: BitrixMailHelperMailbox
  • Вызов: Mailbox::sync
public function sync($syncCounters = true)
{
	global $DB;

	/*
		Setting a new time for an attempt to synchronize the mailbox
		through the agent for users with a free tariff
	*/
	if (!LicenseManager::isSyncAvailable() || !LicenseManager::checkTheMailboxForSyncAvailability($this->mailbox['ID']))
	{
		$this->mailbox['OPTIONS']['next_sync'] = time() + 3600 * 24;

		return 0;
	}

	/*
	Do not start synchronization if no more than static::getTimeout() have passed since the previous one
	*/
	if (time() - $this->mailbox['SYNC_LOCK'] < static::getTimeout())
	{
		return 0;
	}

	$this->mailbox['SYNC_LOCK'] = time();

	/*
	Additional check that the quota has not been exceeded
	since the actual creation of the mailbox instance in php
	*/
	if ($this->isTimeQuotaExceeded())
	{
		return 0;
	}

	$this->session = md5(uniqid(''));

	$this->syncOutgoing();
	$this->restoringConsistency();
	$this->reSyncStartPage();

	$lockSql = sprintf(
		'UPDATE b_mail_mailbox SET SYNC_LOCK = %u WHERE ID = %u AND (SYNC_LOCK IS NULL OR SYNC_LOCK < %u)',
		$this->mailbox['SYNC_LOCK'], $this->mailbox['ID'], $this->mailbox['SYNC_LOCK'] - static::getTimeout()
	);

	/*
	If the time record for blocking synchronization has not been added to the table,
	we will have to abort synchronization
	*/
	if (!$DB->query($lockSql)->affectedRowsCount())
	{
		return 0;
	}

	$mailboxSyncManager = new MailboxMailboxSyncManager($this->mailbox['USER_ID']);
	if ($this->mailbox['USER_ID'] > 0)
	{
		$mailboxSyncManager->setSyncStartedData($this->mailbox['ID']);
	}

	$syncReport = $this->syncInternal();
	$count = $syncReport['syncCount'];

	if($syncReport['reSyncStatus'])
	{
		/*
		When folders are successfully resynchronized,
		allow messages that were left to be moved to be deleted
		*/
		MailMailMessageUidTable::updateList(
			[
				'=MAILBOX_ID' => $this->mailbox['ID'],
				'=MSG_UID' => 0,
				'=IS_OLD' => 'M',
			],
			[
				'IS_OLD' => 'R',
			],
		);
	}

	$success = $count !== false && $this->errors->isEmpty();

	$syncUnlock = $this->isTimeQuotaExceeded() ? 0 : -1;

	$interval = max(1, (int) $this->mailbox['PERIOD_CHECK']) * 60;
	$syncErrors = max(0, (int) $this->mailbox['OPTIONS']['sync_errors']);

	if ($count === false)
	{
		$syncErrors++;

		$maxInterval = 3600 * 24 * 7;
		for ($i = 1; $i < $syncErrors && $interval < $maxInterval; $i++)
		{
			$interval = min($interval * ($i + 1), $maxInterval);
		}
	}
	else
	{
		$syncErrors = 0;

		$interval = $syncUnlock < 0 ? $interval : min($count > 0 ? 60 : 600, $interval);
	}

	$this->mailbox['OPTIONS']['sync_errors'] = $syncErrors;
	$this->mailbox['OPTIONS']['next_sync'] = time() + $interval;

	$optionsValue = $this->mailbox['OPTIONS'];

	$unlockSql = sprintf(
		"UPDATE b_mail_mailbox SET SYNC_LOCK = %d, OPTIONS = '%s' WHERE ID = %u AND SYNC_LOCK = %u",
		$syncUnlock,
		$DB->forSql(serialize($optionsValue)),
		$this->mailbox['ID'],
		$this->mailbox['SYNC_LOCK']
	);
	if ($DB->query($unlockSql)->affectedRowsCount())
	{
		$this->mailbox['SYNC_LOCK'] = $syncUnlock;
	}

	$lastSyncResult = $this->getLastSyncResult();

	$this->pushSyncStatus(
		array(
			'new' => $count,
			'updated' => $lastSyncResult['updatedMessages'],
			'deleted' => $lastSyncResult['deletedMessages'],
			'complete' => $this->mailbox['SYNC_LOCK'] < 0,
		),
		true
	);

	$this->notifyNewMessages();

	if ($this->mailbox['USER_ID'] > 0)
	{
		$mailboxSyncManager->setSyncStatus($this->mailbox['ID'], $success, time());
	}

	if($syncCounters)
	{
		$this->syncCounters();
	}

	return $count;
}