[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * Publishes feed stories into JIRA, using the "JIRA Issues" field to identify 5 * linked issues. 6 */ 7 final class DoorkeeperFeedWorkerJIRA extends DoorkeeperFeedWorker { 8 9 private $provider; 10 11 12 /* -( Publishing Stories )------------------------------------------------- */ 13 14 15 /** 16 * This worker is enabled when a JIRA authentication provider is active. 17 */ 18 public function isEnabled() { 19 return (bool)PhabricatorJIRAAuthProvider::getJIRAProvider(); 20 } 21 22 23 /** 24 * Publishes stories into JIRA using the JIRA API. 25 */ 26 protected function publishFeedStory() { 27 $story = $this->getFeedStory(); 28 $viewer = $this->getViewer(); 29 $provider = $this->getProvider(); 30 $object = $this->getStoryObject(); 31 $publisher = $this->getPublisher(); 32 33 $jira_issue_phids = PhabricatorEdgeQuery::loadDestinationPHIDs( 34 $object->getPHID(), 35 PhabricatorEdgeConfig::TYPE_PHOB_HAS_JIRAISSUE); 36 if (!$jira_issue_phids) { 37 $this->log("Story is about an object with no linked JIRA issues.\n"); 38 return; 39 } 40 41 $xobjs = id(new DoorkeeperExternalObjectQuery()) 42 ->setViewer($viewer) 43 ->withPHIDs($jira_issue_phids) 44 ->execute(); 45 46 if (!$xobjs) { 47 $this->log("Story object has no corresponding external JIRA objects.\n"); 48 return; 49 } 50 51 $try_users = $this->findUsersToPossess(); 52 if (!$try_users) { 53 $this->log("No users to act on linked JIRA objects.\n"); 54 return; 55 } 56 57 $story_text = $this->renderStoryText(); 58 59 $xobjs = mgroup($xobjs, 'getApplicationDomain'); 60 foreach ($xobjs as $domain => $xobj_list) { 61 $accounts = id(new PhabricatorExternalAccountQuery()) 62 ->setViewer($viewer) 63 ->withUserPHIDs($try_users) 64 ->withAccountTypes(array($provider->getProviderType())) 65 ->withAccountDomains(array($domain)) 66 ->requireCapabilities( 67 array( 68 PhabricatorPolicyCapability::CAN_VIEW, 69 PhabricatorPolicyCapability::CAN_EDIT, 70 )) 71 ->execute(); 72 // Reorder accounts in the original order. 73 // TODO: This needs to be adjusted if/when we allow you to link multiple 74 // accounts. 75 $accounts = mpull($accounts, null, 'getUserPHID'); 76 $accounts = array_select_keys($accounts, $try_users); 77 78 foreach ($xobj_list as $xobj) { 79 foreach ($accounts as $account) { 80 try { 81 $provider->newJIRAFuture( 82 $account, 83 'rest/api/2/issue/'.$xobj->getObjectID().'/comment', 84 'POST', 85 array( 86 'body' => $story_text, 87 ))->resolveJSON(); 88 break; 89 } catch (HTTPFutureResponseStatus $ex) { 90 phlog($ex); 91 $this->log( 92 "Failed to update object %s using user %s.\n", 93 $xobj->getObjectID(), 94 $account->getUserPHID()); 95 } 96 } 97 } 98 } 99 } 100 101 102 /* -( Internals )---------------------------------------------------------- */ 103 104 105 /** 106 * Get the active JIRA provider. 107 * 108 * @return PhabricatorJIRAAuthProvider Active JIRA auth provider. 109 * @task internal 110 */ 111 private function getProvider() { 112 if (!$this->provider) { 113 $provider = PhabricatorJIRAAuthProvider::getJIRAProvider(); 114 if (!$provider) { 115 throw new PhabricatorWorkerPermanentFailureException( 116 'No JIRA provider configured.'); 117 } 118 $this->provider = $provider; 119 } 120 return $this->provider; 121 } 122 123 124 /** 125 * Get a list of users to act as when publishing into JIRA. 126 * 127 * @return list<phid> Candidate user PHIDs to act as when publishing this 128 * story. 129 * @task internal 130 */ 131 private function findUsersToPossess() { 132 $object = $this->getStoryObject(); 133 $publisher = $this->getPublisher(); 134 $data = $this->getFeedStory()->getStoryData(); 135 136 // Figure out all the users related to the object. Users go into one of 137 // four buckets. For JIRA integration, we don't care about which bucket 138 // a user is in, since we just want to publish an update to linked objects. 139 140 $owner_phid = $publisher->getOwnerPHID($object); 141 $active_phids = $publisher->getActiveUserPHIDs($object); 142 $passive_phids = $publisher->getPassiveUserPHIDs($object); 143 $follow_phids = $publisher->getCCUserPHIDs($object); 144 145 $all_phids = array_merge( 146 array($owner_phid), 147 $active_phids, 148 $passive_phids, 149 $follow_phids); 150 $all_phids = array_unique(array_filter($all_phids)); 151 152 // Even if the actor isn't a reviewer, etc., try to use their account so 153 // we can post in the correct voice. If we miss, we'll try all the other 154 // related users. 155 156 $try_users = array_merge( 157 array($data->getAuthorPHID()), 158 $all_phids); 159 $try_users = array_filter($try_users); 160 161 return $try_users; 162 } 163 164 private function renderStoryText() { 165 $object = $this->getStoryObject(); 166 $publisher = $this->getPublisher(); 167 168 $text = $publisher->getStoryText($object); 169 $uri = $publisher->getObjectURI($object); 170 171 return $text."\n\n".$uri; 172 } 173 174 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |