@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 PhabricatorCacheEngine extends Phobject {
4
5 public function getViewer() {
6 return PhabricatorUser::getOmnipotentUser();
7 }
8
9 public function updateObject($object) {
10 $objects = array(
11 $object->getPHID() => $object,
12 );
13
14 $new_objects = $objects;
15 while (true) {
16 $discovered_objects = array();
17 $load = array();
18
19 $extensions = PhabricatorCacheEngineExtension::getAllExtensions();
20 foreach ($extensions as $key => $extension) {
21 $discoveries = $extension->discoverLinkedObjects($this, $new_objects);
22 if (!is_array($discoveries)) {
23 throw new Exception(
24 pht(
25 'Cache engine extension "%s" did not return a list of linked '.
26 'objects.',
27 get_class($extension)));
28 }
29
30 foreach ($discoveries as $discovery) {
31 if ($discovery === null) {
32 // This is allowed because it makes writing extensions a lot
33 // easier if they don't have to check that related PHIDs are
34 // actually set to something.
35 continue;
36 }
37
38 $is_phid = is_string($discovery);
39 if ($is_phid) {
40 $phid = $discovery;
41 } else {
42 $phid = $discovery->getPHID();
43 if (!$phid) {
44 throw new Exception(
45 pht(
46 'Cache engine extension "%s" returned object (of class '.
47 '"%s") with no PHID.',
48 get_class($extension),
49 get_class($discovery)));
50 }
51 }
52
53 if (isset($objects[$phid])) {
54 continue;
55 }
56
57 if ($is_phid) {
58 $load[$phid] = $phid;
59 } else {
60 $objects[$phid] = $discovery;
61 $discovered_objects[$phid] = $discovery;
62
63 // If another extension only knew about the PHID of this object,
64 // we don't need to load it any more.
65 unset($load[$phid]);
66 }
67 }
68 }
69
70 if ($load) {
71 $load_objects = id(new PhabricatorObjectQuery())
72 ->setViewer($this->getViewer())
73 ->withPHIDs($load)
74 ->execute();
75 foreach ($load_objects as $phid => $loaded_object) {
76 $objects[$phid] = $loaded_object;
77 $discovered_objects[$phid] = $loaded_object;
78 }
79 }
80
81 // If we didn't find anything new to update, we're all set.
82 if (!$discovered_objects) {
83 break;
84 }
85
86 $new_objects = $discovered_objects;
87 }
88
89 foreach ($extensions as $extension) {
90 $extension->deleteCaches($this, $objects);
91 }
92 }
93
94}