Path: blob/master/src/applications/doorkeeper/bridge/DoorkeeperBridgeGitHubUser.php
12256 views
<?php12final class DoorkeeperBridgeGitHubUser3extends DoorkeeperBridgeGitHub {45const OBJTYPE_GITHUB_USER = 'github.user';67public function canPullRef(DoorkeeperObjectRef $ref) {8if (!parent::canPullRef($ref)) {9return false;10}1112if ($ref->getObjectType() !== self::OBJTYPE_GITHUB_USER) {13return false;14}1516return true;17}1819public function pullRefs(array $refs) {20$token = $this->getGitHubAccessToken();21if (!strlen($token)) {22return null;23}2425$template = id(new PhutilGitHubFuture())26->setAccessToken($token);2728$futures = array();29$id_map = mpull($refs, 'getObjectID', 'getObjectKey');30foreach ($id_map as $key => $id) {31// GitHub doesn't provide a way to query for users by ID directly, but we32// can list all users, ordered by ID, starting at some particular ID,33// with a page size of one, which will achieve the desired effect.34$one_less = ($id - 1);35$uri = "/users?since={$one_less}&per_page=1";3637$data = array();38$futures[$key] = id(clone $template)39->setRawGitHubQuery($uri, $data);40}4142$results = array();43$failed = array();44foreach (new FutureIterator($futures) as $key => $future) {45try {46$results[$key] = $future->resolve();47} catch (Exception $ex) {48if (($ex instanceof HTTPFutureResponseStatus) &&49($ex->getStatusCode() == 404)) {50// TODO: Do we end up here for deleted objects and invisible51// objects?52} else {53phlog($ex);54$failed[$key] = $ex;55}56}57}5859$viewer = $this->getViewer();6061foreach ($refs as $ref) {62$ref->setAttribute('name', pht('GitHub User %s', $ref->getObjectID()));6364$did_fail = idx($failed, $ref->getObjectKey());65if ($did_fail) {66$ref->setSyncFailed(true);67continue;68}6970$result = idx($results, $ref->getObjectKey());71if (!$result) {72continue;73}7475$body = $result->getBody();76if (!is_array($body) || !count($body)) {77$ref->setSyncFailed(true);78continue;79}8081$spec = head($body);82if (!is_array($spec)) {83$ref->setSyncFailed(true);84continue;85}8687// Because we're using a paging query to load each user, if a user (say,88// user ID 123) does not exist for some reason, we might get the next89// user (say, user ID 124) back. Make sure the user we got back is really90// the user we expect.91$id = idx($spec, 'id');92if ($id !== $ref->getObjectID()) {93$ref->setSyncFailed(true);94continue;95}9697$ref->setIsVisible(true);98$ref->setAttribute('api.raw', $spec);99$ref->setAttribute('name', $spec['login']);100101$obj = $ref->getExternalObject();102$this->fillObjectFromData($obj, $spec);103$this->saveExternalObject($ref, $obj);104}105}106107public function fillObjectFromData(DoorkeeperExternalObject $obj, $spec) {108$uri = $spec['html_url'];109$obj->setObjectURI($uri);110111$login = $spec['login'];112113$obj->setDisplayName(pht('%s <%s>', $login, pht('GitHub')));114}115116}117118119