/
PhabricatorAsanaConfigOptions.php
164 lines (137 loc) · 4.66 KB
/
PhabricatorAsanaConfigOptions.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
<?php
final class PhabricatorAsanaConfigOptions
extends PhabricatorApplicationConfigOptions {
public function getName() {
return pht('Integration with Asana');
}
public function getDescription() {
return pht('Asana integration options.');
}
public function getFontIcon() {
return 'fa-exchange';
}
public function getGroup() {
return 'core';
}
public function getOptions() {
return array(
$this->newOption('asana.workspace-id', 'string', null)
->setSummary(pht('Asana Workspace ID to publish into.'))
->setDescription(
pht(
'To enable synchronization into Asana, enter an Asana Workspace '.
'ID here.'.
"\n\n".
"NOTE: This feature is new and experimental.")),
$this->newOption('asana.project-ids', 'wild', null)
->setSummary(pht('Optional Asana projects to use as application tags.'))
->setDescription(
pht(
'When Phabricator creates tasks in Asana, it can add the tasks '.
'to Asana projects based on which application the corresponding '.
'object in Phabricator comes from. For example, you can add code '.
'reviews in Asana to a "Differential" project.'.
"\n\n".
'NOTE: This feature is new and experimental.')),
);
}
public function renderContextualDescription(
PhabricatorConfigOption $option,
AphrontRequest $request) {
switch ($option->getKey()) {
case 'asana.workspace-id':
break;
case 'asana.project-ids':
return $this->renderContextualProjectDescription($option, $request);
default:
return parent::renderContextualDescription($option, $request);
}
$viewer = $request->getUser();
$provider = PhabricatorAsanaAuthProvider::getAsanaProvider();
if (!$provider) {
return null;
}
$account = id(new PhabricatorExternalAccountQuery())
->setViewer($viewer)
->withUserPHIDs(array($viewer->getPHID()))
->withAccountTypes(array($provider->getProviderType()))
->withAccountDomains(array($provider->getProviderDomain()))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$account) {
return null;
}
$token = $provider->getOAuthAccessToken($account);
if (!$token) {
return null;
}
try {
$workspaces = id(new PhutilAsanaFuture())
->setAccessToken($token)
->setRawAsanaQuery('workspaces')
->resolve();
} catch (Exception $ex) {
return null;
}
if (!$workspaces) {
return null;
}
$out = array();
$out[] = sprintf(
'| %s | %s |',
pht('Workspace ID'),
pht('Workspace Name'));
$out[] = '| ------------ | -------------- |';
foreach ($workspaces as $workspace) {
$out[] = sprintf('| `%s` | `%s` |', $workspace['id'], $workspace['name']);
}
$out = implode("\n", $out);
$out = pht(
"The Asana Workspaces your linked account has access to are:\n\n%s",
$out);
return PhabricatorMarkupEngine::renderOneObject(
id(new PhabricatorMarkupOneOff())->setContent($out),
'default',
$viewer);
}
private function renderContextualProjectDescription(
PhabricatorConfigOption $option,
AphrontRequest $request) {
$viewer = $request->getUser();
$publishers = id(new PhutilClassMapQuery())
->setAncestorClass('DoorkeeperFeedStoryPublisher')
->execute();
$out = array();
$out[] = pht(
'To specify projects to add tasks to, enter a JSON map with publisher '.
'class names as keys and a list of project IDs as values. For example, '.
'to put Differential tasks into Asana projects with IDs `123` and '.
'`456`, enter:'.
"\n\n".
" lang=txt\n".
" {\n".
" \"DifferentialDoorkeeperRevisionFeedStoryPublisher\" : [123, 456]\n".
" }\n");
$out[] = pht('Available publishers class names are:');
foreach ($publishers as $publisher) {
$out[] = ' - `'.get_class($publisher).'`';
}
$out[] = pht(
'You can find an Asana project ID by clicking the project in Asana and '.
'then examining the URL:'.
"\n\n".
" lang=txt\n".
" https://app.asana.com/0/12345678901234567890/111111111111111111\n".
" ^^^^^^^^^^^^^^^^^^^^\n".
" This is the ID to use.\n");
$out = implode("\n", $out);
return PhabricatorMarkupEngine::renderOneObject(
id(new PhabricatorMarkupOneOff())->setContent($out),
'default',
$viewer);
}
}