[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/doorkeeper/bridge/ -> DoorkeeperBridgeAsana.php (source)

   1  <?php
   2  
   3  final class DoorkeeperBridgeAsana extends DoorkeeperBridge {
   4  
   5    const APPTYPE_ASANA   = 'asana';
   6    const APPDOMAIN_ASANA = 'asana.com';
   7    const OBJTYPE_TASK    = 'asana:task';
   8  
   9    public function canPullRef(DoorkeeperObjectRef $ref) {
  10      if ($ref->getApplicationType() != self::APPTYPE_ASANA) {
  11        return false;
  12      }
  13  
  14      if ($ref->getApplicationDomain() != self::APPDOMAIN_ASANA) {
  15        return false;
  16      }
  17  
  18      $types = array(
  19        self::OBJTYPE_TASK => true,
  20      );
  21  
  22      return isset($types[$ref->getObjectType()]);
  23    }
  24  
  25    public function pullRefs(array $refs) {
  26  
  27      $id_map = mpull($refs, 'getObjectID', 'getObjectKey');
  28      $viewer = $this->getViewer();
  29  
  30      $provider = PhabricatorAsanaAuthProvider::getAsanaProvider();
  31      if (!$provider) {
  32        return;
  33      }
  34  
  35      $accounts = id(new PhabricatorExternalAccountQuery())
  36        ->setViewer($viewer)
  37        ->withUserPHIDs(array($viewer->getPHID()))
  38        ->withAccountTypes(array($provider->getProviderType()))
  39        ->withAccountDomains(array($provider->getProviderDomain()))
  40        ->requireCapabilities(
  41          array(
  42            PhabricatorPolicyCapability::CAN_VIEW,
  43            PhabricatorPolicyCapability::CAN_EDIT,
  44          ))
  45        ->execute();
  46  
  47      if (!$accounts) {
  48        return $this->didFailOnMissingLink();
  49      }
  50  
  51      // TODO: If the user has several linked Asana accounts, we just pick the
  52      // first one arbitrarily. We might want to try using all of them or do
  53      // something with more finesse. There's no UI way to link multiple accounts
  54      // right now so this is currently moot.
  55      $account = head($accounts);
  56  
  57      $token = $provider->getOAuthAccessToken($account);
  58      if (!$token) {
  59        return;
  60      }
  61  
  62      $template = id(new PhutilAsanaFuture())
  63        ->setAccessToken($token);
  64  
  65      $futures = array();
  66      foreach ($id_map as $key => $id) {
  67        $futures[$key] = id(clone $template)
  68          ->setRawAsanaQuery("tasks/{$id}");
  69      }
  70  
  71      $results = array();
  72      $failed = array();
  73      foreach (Futures($futures) as $key => $future) {
  74        try {
  75          $results[$key] = $future->resolve();
  76        } catch (Exception $ex) {
  77          if (($ex instanceof HTTPFutureResponseStatus) &&
  78              ($ex->getStatusCode() == 404)) {
  79            // This indicates that the object has been deleted (or never existed,
  80            // or isn't visible to the current user) but it's a successful sync of
  81            // an object which isn't visible.
  82          } else {
  83            // This is something else, so consider it a synchronization failure.
  84            phlog($ex);
  85            $failed[$key] = $ex;
  86          }
  87        }
  88      }
  89  
  90      foreach ($refs as $ref) {
  91        $ref->setAttribute('name', pht('Asana Task %s', $ref->getObjectID()));
  92  
  93        $did_fail = idx($failed, $ref->getObjectKey());
  94        if ($did_fail) {
  95          $ref->setSyncFailed(true);
  96          continue;
  97        }
  98  
  99        $result = idx($results, $ref->getObjectKey());
 100        if (!$result) {
 101          continue;
 102        }
 103  
 104        $ref->setIsVisible(true);
 105        $ref->setAttribute('asana.data', $result);
 106        $ref->setAttribute('fullname', pht('Asana: %s', $result['name']));
 107        $ref->setAttribute('title', $result['name']);
 108        $ref->setAttribute('description', $result['notes']);
 109  
 110        $obj = $ref->getExternalObject();
 111        if ($obj->getID()) {
 112          continue;
 113        }
 114  
 115        $this->fillObjectFromData($obj, $result);
 116  
 117        $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
 118          $obj->save();
 119        unset($unguarded);
 120      }
 121    }
 122  
 123    public function fillObjectFromData(DoorkeeperExternalObject $obj, $result) {
 124      $id = $result['id'];
 125      $uri = "https://app.asana.com/0/{$id}/{$id}";
 126      $obj->setObjectURI($uri);
 127    }
 128  
 129  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1