@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 PhabricatorDraftEngine
4 extends Phobject {
5
6 private $viewer;
7 private $object;
8 private $hasVersionedDraft;
9 private $versionedDraft;
10
11 final public function setViewer(PhabricatorUser $viewer) {
12 $this->viewer = $viewer;
13 return $this;
14 }
15
16 final public function getViewer() {
17 return $this->viewer;
18 }
19
20 final public function setObject($object) {
21 $this->object = $object;
22 return $this;
23 }
24
25 final public function getObject() {
26 return $this->object;
27 }
28
29 final public function setVersionedDraft(
30 ?PhabricatorVersionedDraft $draft = null) {
31 $this->hasVersionedDraft = true;
32 $this->versionedDraft = $draft;
33 return $this;
34 }
35
36 final public function getVersionedDraft() {
37 if (!$this->hasVersionedDraft) {
38 $draft = PhabricatorVersionedDraft::loadDraft(
39 $this->getObject()->getPHID(),
40 $this->getViewer()->getPHID());
41 $this->setVersionedDraft($draft);
42 }
43
44 return $this->versionedDraft;
45 }
46
47 protected function hasVersionedDraftContent() {
48 $draft = $this->getVersionedDraft();
49 if (!$draft) {
50 return false;
51 }
52
53 if ($draft->getProperty('comment')) {
54 return true;
55 }
56
57 if ($draft->getProperty('actions')) {
58 return true;
59 }
60
61 return false;
62 }
63
64 protected function hasCustomDraftContent() {
65 return false;
66 }
67
68 final protected function hasAnyDraftContent() {
69 if ($this->hasVersionedDraftContent()) {
70 return true;
71 }
72
73 if ($this->hasCustomDraftContent()) {
74 return true;
75 }
76
77 return false;
78 }
79
80 final public function synchronize() {
81 $object_phid = $this->getObject()->getPHID();
82 $viewer_phid = $this->getViewer()->getPHID();
83
84 $has_draft = $this->hasAnyDraftContent();
85
86 $draft_type = PhabricatorObjectHasDraftEdgeType::EDGECONST;
87 $editor = new PhabricatorEdgeEditor();
88
89 if ($has_draft) {
90 $editor->addEdge($object_phid, $draft_type, $viewer_phid);
91 } else {
92 $editor->removeEdge($object_phid, $draft_type, $viewer_phid);
93 }
94
95 $editor->save();
96 }
97
98 /**
99 * @param PhabricatorUser $viewer
100 * @param array<PhabricatorDraftInterface> $objects
101 */
102 final public static function attachDrafts(
103 PhabricatorUser $viewer,
104 array $objects) {
105 assert_instances_of($objects, PhabricatorDraftInterface::class);
106
107 $viewer_phid = $viewer->getPHID();
108
109 if (!$viewer_phid) {
110 // Viewers without a valid PHID can never have drafts.
111 foreach ($objects as $object) {
112 $object->attachHasDraft($viewer, false);
113 }
114 return;
115 } else {
116 $draft_type = PhabricatorObjectHasDraftEdgeType::EDGECONST;
117
118 $edge_query = id(new PhabricatorEdgeQuery())
119 ->withSourcePHIDs(mpull($objects, 'getPHID'))
120 ->withEdgeTypes(
121 array(
122 $draft_type,
123 ))
124 ->withDestinationPHIDs(array($viewer_phid));
125
126 $edge_query->execute();
127
128 foreach ($objects as $object) {
129 $has_draft = (bool)$edge_query->getDestinationPHIDs(
130 array(
131 $object->getPHID(),
132 ));
133
134 $object->attachHasDraft($viewer, $has_draft);
135 }
136 }
137 }
138
139}