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

	$worker = function ($id, $msgId, &$i)
	{
		global $DB;

		$stack = array(
			array(
				array($id, $msgId, false),
			),
		);

		$excerpt = array();

		do
		{
			$level = array_pop($stack);

			while ($level)
			{
				[$id, $msgId, $skip] = array_shift($level);

				if (!$skip)
				{
					$excerpt[] = $id;

					$DB->query(sprintf(
						'UPDATE b_mail_message SET LEFT_MARGIN = %2$u, RIGHT_MARGIN = %3$u WHERE ID = %1$u',
						$id, ++$i, ++$i
					));

					if (!empty($msgId))
					{
						$replies = array();

						$res = MailMailMessageTable::getList(array(
							'select' => array(
								'ID',
								'MSG_ID',
							),
							'filter' => array(
								'=MAILBOX_ID' => $this->mailbox['ID'],
								'=IN_REPLY_TO' => $msgId,
							),
							'order' => array(
								'FIELD_DATE' => 'ASC',
							),
						));

						while ($item = $res->fetch())
						{
							if (!in_array($item['ID'], $excerpt))
							{
								$replies[] = array($item['ID'], $item['MSG_ID'], false);
							}
						}

						if ($replies)
						{
							array_unshift($level, array($id, $msgId, true));

							array_push($stack, $level, $replies);
							$i--;

							continue 2;
						}
					}
				}
				else
				{
					$DB->query(sprintf(
						'UPDATE b_mail_message SET RIGHT_MARGIN = %2$u WHERE ID = %1$u',
						$id, ++$i
					));
				}
			}
		}
		while ($stack);
	};

	if (!empty($message))
	{
		if (empty($message['ID']))
		{
			throw new MainArgumentException("Argument 'message' is not valid");
		}

		$item = $DB->query(sprintf(
			'SELECT GREATEST(M1, M2) AS I FROM (SELECT
				(SELECT RIGHT_MARGIN FROM b_mail_message WHERE MAILBOX_ID = %1$u AND RIGHT_MARGIN > 0 ORDER BY LEFT_MARGIN ASC LIMIT 1) M1,
				(SELECT RIGHT_MARGIN FROM b_mail_message WHERE MAILBOX_ID = %1$u AND RIGHT_MARGIN > 0 ORDER BY LEFT_MARGIN DESC LIMIT 1) M2
			) M',
			$this->mailbox['ID']
		))->fetch();

		$i = empty($item['I']) ? 0 : $item['I'];

		$worker($message['ID'], $message['MSG_ID'], $i);
	}
	else
	{
		$DB->query(sprintf(
			'UPDATE b_mail_message SET LEFT_MARGIN = 0, RIGHT_MARGIN = 0 WHERE MAILBOX_ID = %u',
			$this->mailbox['ID']
		));

		$i = 0;

		$res = $DB->query(sprintf(
			"SELECT ID, MSG_ID FROM b_mail_message M WHERE MAILBOX_ID = %u AND (
				IN_REPLY_TO IS NULL OR IN_REPLY_TO = '' OR NOT EXISTS (
					SELECT 1 FROM b_mail_message WHERE MAILBOX_ID = M.MAILBOX_ID AND MSG_ID = M.IN_REPLY_TO
				)
			)",
			$this->mailbox['ID']
		));

		while ($item = $res->fetch())
		{
			$worker($item['ID'], $item['MSG_ID'], $i);
		}

		// crosslinked messages
		$query = sprintf(
			'SELECT ID, MSG_ID FROM b_mail_message
				WHERE MAILBOX_ID = %u AND LEFT_MARGIN = 0
				ORDER BY FIELD_DATE ASC LIMIT 1',
			$this->mailbox['ID']
		);
		while ($item = $DB->query($query)->fetch())
		{
			$worker($item['ID'], $item['MSG_ID'], $i);
		}
	}
}