1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-25 08:12:40 +01:00
phorge-phorge/src/applications/doorkeeper/bridge/DoorkeeperBridgeAsana.php
epriestley 4ca38612f2 Add DoorkeeperExternalObjectQuery, expose more ref/import APIs
Summary:
Ref T2852.

  - Broadly, we support "I have a Ref, I need a PHID" well but not "I have a PHID, I need a Ref".
  - Add DoorkeeperExternalObjectQuery, and use it to query ExternalObjects.
  - Allow external objects to be imported by their internal PHIDs. Basically, if we have an edge pointing at an ExternalObject, we can say "load all the data about this" from just the PHID and have it hit all the same code.
  - Allow construction of Refs from ExternalObjects. This makes the "I have a PHID, I need a Ref" easier.

Test Plan:
  - Verified Asana links still enrich properly at display time.
  - Used in future revision.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T2852

Differential Revision: https://secure.phabricator.com/D6294
2013-06-25 16:30:44 -07:00

94 lines
2.6 KiB
PHP

<?php
final class DoorkeeperBridgeAsana extends DoorkeeperBridge {
public function canPullRef(DoorkeeperObjectRef $ref) {
return ($ref->getApplicationType() == 'asana') &&
($ref->getApplicationDomain() == 'asana.com') &&
($ref->getObjectType() == 'asana:task');
}
public function pullRefs(array $refs) {
$id_map = mpull($refs, 'getObjectID', 'getObjectKey');
$viewer = $this->getViewer();
$provider = PhabricatorAuthProviderOAuthAsana::getAsanaProvider();
if (!$provider) {
return;
}
$accounts = id(new PhabricatorExternalAccountQuery())
->setViewer($viewer)
->withUserPHIDs(array($viewer->getPHID()))
->withAccountTypes(array($provider->getProviderType()))
->withAccountDomains(array($provider->getProviderDomain()))
->execute();
if (!$accounts) {
return;
}
// TODO: If the user has several linked Asana accounts, we just pick the
// first one arbitrarily. We might want to try using all of them or do
// something with more finesse. There's no UI way to link multiple accounts
// right now so this is currently moot.
$account = head($accounts);
$token = $provider->getOAuthAccessToken($account);
if (!$token) {
return;
}
$template = id(new PhutilAsanaFuture())
->setAccessToken($token);
$futures = array();
foreach ($id_map as $key => $id) {
$futures[$key] = id(clone $template)
->setRawAsanaQuery("tasks/{$id}");
}
$results = array();
foreach (Futures($futures) as $key => $future) {
try {
$results[$key] = $future->resolve();
} catch (Exception $ex) {
// TODO: For now, ignore this stuff.
}
}
foreach ($refs as $ref) {
$ref->setAttribute('name', pht('Asana Task %s', $ref->getObjectID()));
$result = idx($results, $ref->getObjectKey());
if (!$result) {
continue;
}
$ref->setIsVisible(true);
$ref->setAttribute('asana.data', $result);
$ref->setAttribute('fullname', pht('Asana: %s', $result['name']));
$ref->setAttribute('title', $result['name']);
$ref->setAttribute('description', $result['notes']);
$obj = $ref->getExternalObject();
if ($obj->getID()) {
continue;
}
$this->fillObjectFromData($obj, $result);
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
$obj->save();
unset($unguarded);
}
}
public function fillObjectFromData(DoorkeeperExternalObject $obj, $result) {
$id = $result['id'];
$uri = "https://app.asana.com/0/{$id}/{$id}";
$obj->setObjectURI($uri);
}
}