Correct a parameter order swap in "diffusion.historyquery" for Mercurial
[phabricator.git] / src / applications / doorkeeper / bridge / DoorkeeperBridgeGitHubUser.php
blobef31826eb378db5af5e60ed2ab871115af7e9890
1 <?php
3 final class DoorkeeperBridgeGitHubUser
4 extends DoorkeeperBridgeGitHub {
6 const OBJTYPE_GITHUB_USER = 'github.user';
8 public function canPullRef(DoorkeeperObjectRef $ref) {
9 if (!parent::canPullRef($ref)) {
10 return false;
13 if ($ref->getObjectType() !== self::OBJTYPE_GITHUB_USER) {
14 return false;
17 return true;
20 public function pullRefs(array $refs) {
21 $token = $this->getGitHubAccessToken();
22 if (!strlen($token)) {
23 return null;
26 $template = id(new PhutilGitHubFuture())
27 ->setAccessToken($token);
29 $futures = array();
30 $id_map = mpull($refs, 'getObjectID', 'getObjectKey');
31 foreach ($id_map as $key => $id) {
32 // GitHub doesn't provide a way to query for users by ID directly, but we
33 // can list all users, ordered by ID, starting at some particular ID,
34 // with a page size of one, which will achieve the desired effect.
35 $one_less = ($id - 1);
36 $uri = "/users?since={$one_less}&per_page=1";
38 $data = array();
39 $futures[$key] = id(clone $template)
40 ->setRawGitHubQuery($uri, $data);
43 $results = array();
44 $failed = array();
45 foreach (new FutureIterator($futures) as $key => $future) {
46 try {
47 $results[$key] = $future->resolve();
48 } catch (Exception $ex) {
49 if (($ex instanceof HTTPFutureResponseStatus) &&
50 ($ex->getStatusCode() == 404)) {
51 // TODO: Do we end up here for deleted objects and invisible
52 // objects?
53 } else {
54 phlog($ex);
55 $failed[$key] = $ex;
60 $viewer = $this->getViewer();
62 foreach ($refs as $ref) {
63 $ref->setAttribute('name', pht('GitHub User %s', $ref->getObjectID()));
65 $did_fail = idx($failed, $ref->getObjectKey());
66 if ($did_fail) {
67 $ref->setSyncFailed(true);
68 continue;
71 $result = idx($results, $ref->getObjectKey());
72 if (!$result) {
73 continue;
76 $body = $result->getBody();
77 if (!is_array($body) || !count($body)) {
78 $ref->setSyncFailed(true);
79 continue;
82 $spec = head($body);
83 if (!is_array($spec)) {
84 $ref->setSyncFailed(true);
85 continue;
88 // Because we're using a paging query to load each user, if a user (say,
89 // user ID 123) does not exist for some reason, we might get the next
90 // user (say, user ID 124) back. Make sure the user we got back is really
91 // the user we expect.
92 $id = idx($spec, 'id');
93 if ($id !== $ref->getObjectID()) {
94 $ref->setSyncFailed(true);
95 continue;
98 $ref->setIsVisible(true);
99 $ref->setAttribute('api.raw', $spec);
100 $ref->setAttribute('name', $spec['login']);
102 $obj = $ref->getExternalObject();
103 $this->fillObjectFromData($obj, $spec);
104 $this->saveExternalObject($ref, $obj);
108 public function fillObjectFromData(DoorkeeperExternalObject $obj, $spec) {
109 $uri = $spec['html_url'];
110 $obj->setObjectURI($uri);
112 $login = $spec['login'];
114 $obj->setDisplayName(pht('%s <%s>', $login, pht('GitHub')));