4 * Coordinates loading object handles.
6 * This is a low-level piece of plumbing which code will not normally interact
7 * with directly. For discussion of the handle pool mechanism, see
8 * @{class:PhabricatorHandleList}.
10 final class PhabricatorHandlePool
extends Phobject
{
13 private $handles = array();
14 private $unloadedPHIDs = array();
16 public function setViewer(PhabricatorUser
$user) {
17 $this->viewer
= $user;
21 public function getViewer() {
25 public function newHandleList(array $phids) {
26 // Mark any PHIDs we haven't loaded yet as unloaded. This will let us bulk
28 foreach ($phids as $phid) {
29 if (empty($this->handles
[$phid])) {
30 $this->unloadedPHIDs
[$phid] = true;
35 foreach ($phids as $phid) {
36 $unique[$phid] = $phid;
39 return id(new PhabricatorHandleList())
40 ->setHandlePool($this)
41 ->setPHIDs(array_values($unique));
44 public function loadPHIDs(array $phids) {
46 foreach ($phids as $phid) {
47 if (empty($this->handles
[$phid])) {
52 foreach ($need as $phid => $ignored) {
53 if (empty($this->unloadedPHIDs
[$phid])) {
56 'Attempting to load PHID "%s", but it was not requested by any '.
62 // If we need any handles, bulk load everything in the queue.
64 // Clear the list of PHIDs that need to be loaded before performing the
65 // actual fetch. This prevents us from looping if we need to reenter the
66 // HandlePool while loading handles.
67 $fetch_phids = array_keys($this->unloadedPHIDs
);
68 $this->unloadedPHIDs
= array();
70 $handles = id(new PhabricatorHandleQuery())
71 ->setViewer($this->getViewer())
72 ->withPHIDs($fetch_phids)
74 $this->handles +
= $handles;
77 return array_select_keys($this->handles
, $phids);