@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3final class PHUIDiffInlineThreader extends Phobject {
4
5 public function reorderAndThreadCommments(array $comments) {
6 $comments = msort($comments, 'getID');
7
8 // Build an empty map of all the comments we actually have. If a comment
9 // is a reply but the parent has gone missing, we don't want it to vanish
10 // completely.
11 $comment_phids = mpull($comments, 'getPHID');
12 $replies = array_fill_keys($comment_phids, array());
13
14 // Now, remove all comments which are replies, leaving only the top-level
15 // comments.
16 foreach ($comments as $key => $comment) {
17 $reply_phid = $comment->getReplyToCommentPHID();
18 if (isset($replies[$reply_phid])) {
19 $replies[$reply_phid][] = $comment;
20 unset($comments[$key]);
21 }
22 }
23
24 // For each top level comment, add the comment, then add any replies
25 // to it. Do this recursively so threads are shown in threaded order.
26 $results = array();
27 foreach ($comments as $comment) {
28 $results[] = $comment;
29 $phid = $comment->getPHID();
30 $descendants = $this->getInlineReplies($replies, $phid, 1);
31 foreach ($descendants as $descendant) {
32 $results[] = $descendant;
33 }
34 }
35
36 // If we have anything left, they were cyclic references. Just dump
37 // them in a the end. This should be impossible, but users are very
38 // creative.
39 foreach ($replies as $phid => $comments) {
40 foreach ($comments as $comment) {
41 $results[] = $comment;
42 }
43 }
44
45 return $results;
46 }
47
48 private function getInlineReplies(array &$replies, $phid, $depth) {
49 $comments = idx($replies, $phid, array());
50 unset($replies[$phid]);
51
52 $results = array();
53 foreach ($comments as $comment) {
54 $results[] = $comment;
55 $descendants = $this->getInlineReplies(
56 $replies,
57 $comment->getPHID(),
58 $depth + 1);
59 foreach ($descendants as $descendant) {
60 $results[] = $descendant;
61 }
62 }
63
64 return $results;
65 }
66}