@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
3abstract class PhabricatorTransactionFactEngine
4 extends PhabricatorFactEngine {
5
6 public function newTransactionGroupsForObject(PhabricatorLiskDAO $object) {
7 $viewer = $this->getViewer();
8
9 $xaction_query = PhabricatorApplicationTransactionQuery::newQueryForObject(
10 $object);
11 $xactions = $xaction_query
12 ->setViewer($viewer)
13 ->withObjectPHIDs(array($object->getPHID()))
14 ->execute();
15
16 $xactions = msortv($xactions, 'newChronologicalSortVector');
17
18 return $this->groupTransactions($xactions);
19 }
20
21 protected function groupTransactions(array $xactions) {
22 // These grouping rules are generally much looser than the display grouping
23 // rules. As long as the same user is editing the task and they don't leave
24 // it alone for a particularly long time, we'll group things together.
25
26 $breaks = array();
27
28 $touch_window = phutil_units('15 minutes in seconds');
29 $user_type = PhabricatorPeopleUserPHIDType::TYPECONST;
30
31 $last_actor = null;
32 $last_epoch = null;
33
34 foreach ($xactions as $key => $xaction) {
35 $this_actor = $xaction->getAuthorPHID();
36 if (phid_get_type($this_actor) != $user_type) {
37 $this_actor = null;
38 }
39
40 if ($this_actor && $last_actor && ($this_actor != $last_actor)) {
41 $breaks[$key] = true;
42 }
43
44 // If too much time passed between changes, group them separately.
45 $this_epoch = $xaction->getDateCreated();
46 if ($last_epoch) {
47 if (($this_epoch - $last_epoch) > $touch_window) {
48 $breaks[$key] = true;
49 }
50 }
51
52 // The clock gets reset every time the same real user touches the
53 // task, but does not reset if an automated actor touches things.
54 if (!$last_actor || ($this_actor == $last_actor)) {
55 $last_epoch = $this_epoch;
56 }
57
58 if ($this_actor && ($last_actor != $this_actor)) {
59 $last_actor = $this_actor;
60 $last_epoch = $this_epoch;
61 }
62 }
63
64 $groups = array();
65 $group = array();
66 foreach ($xactions as $key => $xaction) {
67 if (isset($breaks[$key])) {
68 if ($group) {
69 $groups[] = $group;
70 $group = array();
71 }
72 }
73
74 $group[] = $xaction;
75 }
76
77 if ($group) {
78 $groups[] = $group;
79 }
80
81 return $groups;
82 }
83
84}