/**
  * Get the active JIRA provider.
  *
  * @return PhabricatorJIRAAuthProvider Active JIRA auth provider.
  * @task internal
  */
 private function getProvider()
 {
     if (!$this->provider) {
         $provider = PhabricatorJIRAAuthProvider::getJIRAProvider();
         if (!$provider) {
             throw new PhabricatorWorkerPermanentFailureException(pht('No JIRA provider configured.'));
         }
         $this->provider = $provider;
     }
     return $this->provider;
 }
 public function markupJIRALink($matches)
 {
     $match_domain = $matches[1];
     $match_issue = $matches[2];
     // TODO: When we support multiple instances, deal with them here.
     $provider = PhabricatorJIRAAuthProvider::getJIRAProvider();
     if (!$provider) {
         return $matches[0];
     }
     $jira_base = $provider->getJIRABaseURI();
     if ($match_domain != rtrim($jira_base, '/')) {
         return $matches[0];
     }
     return $this->addDoorkeeperTag(array('href' => $matches[0], 'tag' => array('ref' => array(DoorkeeperBridgeJIRA::APPTYPE_JIRA, $provider->getProviderDomain(), DoorkeeperBridgeJIRA::OBJTYPE_ISSUE, $match_issue))));
 }
 public function pullRefs(array $refs)
 {
     $id_map = mpull($refs, 'getObjectID', 'getObjectKey');
     $viewer = $this->getViewer();
     $provider = PhabricatorJIRAAuthProvider::getJIRAProvider();
     if (!$provider) {
         return;
     }
     $accounts = id(new PhabricatorExternalAccountQuery())->setViewer($viewer)->withUserPHIDs(array($viewer->getPHID()))->withAccountTypes(array($provider->getProviderType()))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->execute();
     if (!$accounts) {
         return $this->didFailOnMissingLink();
     }
     // TODO: When we support multiple JIRA instances, we need to disambiguate
     // issues (perhaps with additional configuration) or cast a wide net
     // (by querying all instances). For now, just query the one instance.
     $account = head($accounts);
     $futures = array();
     foreach ($id_map as $key => $id) {
         $futures[$key] = $provider->newJIRAFuture($account, 'rest/api/2/issue/' . phutil_escape_uri($id), 'GET');
     }
     $results = array();
     $failed = array();
     foreach (new FutureIterator($futures) as $key => $future) {
         try {
             $results[$key] = $future->resolveJSON();
         } catch (Exception $ex) {
             if ($ex instanceof HTTPFutureResponseStatus && $ex->getStatusCode() == 404) {
                 // This indicates that the object has been deleted (or never existed,
                 // or isn't visible to the current user) but it's a successful sync of
                 // an object which isn't visible.
             } else {
                 // This is something else, so consider it a synchronization failure.
                 phlog($ex);
                 $failed[$key] = $ex;
             }
         }
     }
     foreach ($refs as $ref) {
         $ref->setAttribute('name', pht('JIRA %s', $ref->getObjectID()));
         $did_fail = idx($failed, $ref->getObjectKey());
         if ($did_fail) {
             $ref->setSyncFailed(true);
             continue;
         }
         $result = idx($results, $ref->getObjectKey());
         if (!$result) {
             continue;
         }
         $fields = idx($result, 'fields', array());
         $ref->setIsVisible(true);
         $ref->setAttribute('fullname', pht('JIRA %s %s', $result['key'], idx($fields, 'summary')));
         $ref->setAttribute('title', idx($fields, 'summary'));
         $ref->setAttribute('description', idx($result, 'description'));
         $obj = $ref->getExternalObject();
         if ($obj->getID()) {
             continue;
         }
         $this->fillObjectFromData($obj, $result);
         $this->saveExternalObject($ref, $obj);
     }
 }
 public function shouldAppearInApplicationTransactions()
 {
     return PhabricatorJIRAAuthProvider::getJIRAProvider();
 }