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

	if (!MailHelperLicenseManager::isCleanupOldEnabled())
	{
		return true;
	}

	$startTime = time();

	if (time() - $this->mailbox['SYNC_LOCK'] < static::getTimeout())
	{
		return false;
	}

	if ($this->isTimeQuotaExceeded())
	{
		return false;
	}

	$syncUnlock = $this->mailbox['SYNC_LOCK'];

	$lockSql = sprintf(
		'UPDATE b_mail_mailbox SET SYNC_LOCK = %u WHERE ID = %u AND (SYNC_LOCK IS NULL OR SYNC_LOCK < %u)',
		$startTime, $this->mailbox['ID'], $startTime - static::getTimeout()
	);
	if ($DB->query($lockSql)->affectedRowsCount())
	{
		$this->mailbox['SYNC_LOCK'] = $startTime;
	}
	else
	{
		return false;
	}

	$result = true;

	$entity = MailMailMessageUidTable::getEntity();
	$connection = $entity->getConnection();

	$whereConditionForOldMessages = sprintf(
		' (%s)',
		ORMQueryQuery::buildFilterSql(
			$entity,
			array(
				'=MAILBOX_ID' => $this->mailbox['ID'],
				'>MESSAGE_ID' => 0,
				' MainTypeDate::createFromTimestamp(strtotime(sprintf('-%u days', MailHelperLicenseManager::getSyncOldLimit()))),
				'!=IS_OLD' => 'Y',
			)
		)
	);

	$where = sprintf(
		' (%s) AND NOT EXISTS (SELECT 1 FROM %s WHERE (%s) AND (%s)) ',
		ORMQueryQuery::buildFilterSql(
			$entity,
			array(
				'=MAILBOX_ID' => $this->mailbox['ID'],
				'>MESSAGE_ID' => 0,
				' MainTypeDateTime::createFromTimestamp(strtotime(sprintf('-%u days', MailHelperLicenseManager::getSyncOldLimit()))),
			)
		),
		$connection->getSqlHelper()->quote(MailInternalsMessageAccessTable::getTableName()),
		ORMQueryQuery::buildFilterSql(
			$entity,
			array(
				'=MAILBOX_ID' => new MainDBSqlExpression('?#', 'MAILBOX_ID'),
				'=MESSAGE_ID' => new MainDBSqlExpression('?#', 'MESSAGE_ID'),
			)
		),
		ORMQueryQuery::buildFilterSql(
			MailInternalsMessageAccessTable::getEntity(),
			array(
				'=ENTITY_TYPE' => array(
					MailInternalsMessageAccessTable::ENTITY_TYPE_TASKS_TASK,
					MailInternalsMessageAccessTable::ENTITY_TYPE_BLOG_POST,
				),
			)
		)
	);

	$sqlHelper = $connection->getSqlHelper();
	$messageDeleteTable = $sqlHelper->quote(MailInternalsMessageDeleteQueueTable::getTableName());
	$entityTable = $sqlHelper->quote($entity->getDbTableName());
	do
	{
		$selectFrom = sprintf(
			'SELECT ID, MAILBOX_ID, MESSAGE_ID FROM %s WHERE %s ORDER BY ID LIMIT 1000',
			$entityTable,
			$where
		);
		$connection->query($sqlHelper
			->getInsertIgnore($messageDeleteTable, ' (ID, MAILBOX_ID, MESSAGE_ID) ', "($selectFrom)"));

		$connection->query(sprintf(
			"UPDATE %s SET IS_OLD = 'Y', IS_SEEN = 'Y' WHERE %s ORDER BY ID LIMIT 1000",
			$connection->getSqlHelper()->quote($entity->getDbTableName()),
			$whereConditionForOldMessages
		));

		$connection->query(sprintf(
			'UPDATE %s SET MESSAGE_ID = 0 WHERE %s ORDER BY ID LIMIT 1000',
			$connection->getSqlHelper()->quote($entity->getDbTableName()),
			$where
		));

		if ($this->isTimeQuotaExceeded() || time() - $this->checkpoint > 15)
		{
			$result = false;

			break;
		}
	}
	while ($connection->getAffectedRowsCount() >= 1000);

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

	return $result;
}