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);
}
}
}