Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F99209139
DoorkeeperBridgeJIRA.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Wed, Jan 22, 10:02
Size
4 KB
Mime Type
text/x-php
Expires
Fri, Jan 24, 10:02 (2 d)
Engine
blob
Format
Raw Data
Handle
23738850
Attached To
rPH Phabricator
DoorkeeperBridgeJIRA.php
View Options
<?php
final
class
DoorkeeperBridgeJIRA
extends
DoorkeeperBridge
{
const
APPTYPE_JIRA
=
'jira'
;
const
OBJTYPE_ISSUE
=
'jira:issue'
;
public
function
canPullRef
(
DoorkeeperObjectRef
$ref
)
{
if
(
$ref
->
getApplicationType
()
!=
self
::
APPTYPE_JIRA
)
{
return
false
;
}
$types
=
array
(
self
::
OBJTYPE_ISSUE
=>
true
,
);
return
isset
(
$types
[
$ref
->
getObjectType
()]);
}
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
(
Futures
(
$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
);
$unguarded
=
AphrontWriteGuard
::
beginScopedUnguardedWrites
();
$obj
->
save
();
unset
(
$unguarded
);
}
}
public
function
fillObjectFromData
(
DoorkeeperExternalObject
$obj
,
$result
)
{
// Convert the "self" URI, which points at the REST endpoint, into a
// browse URI.
$self
=
idx
(
$result
,
'self'
);
$object_id
=
$obj
->
getObjectID
();
$uri
=
self
::
getJIRAIssueBrowseURIFromJIRARestURI
(
$self
,
$object_id
);
if
(
$uri
!==
null
)
{
$obj
->
setObjectURI
(
$uri
);
}
}
public
static
function
getJIRAIssueBrowseURIFromJIRARestURI
(
$uri
,
$object_id
)
{
$uri
=
new
PhutilURI
(
$uri
);
// The JIRA install might not be at the domain root, so we may need to
// keep an initial part of the path, like "/jira/". Find the API specific
// part of the URI, strip it off, then replace it with the web version.
$path
=
$uri
->
getPath
();
$pos
=
strrpos
(
$path
,
'rest/api/2/issue/'
);
if
(
$pos
===
false
)
{
return
null
;
}
$path
=
substr
(
$path
,
0
,
$pos
);
$path
=
$path
.
'browse/'
.
$object_id
;
$uri
->
setPath
(
$path
);
return
(
string
)
$uri
;
}
}
Event Timeline
Log In to Comment