Page MenuHomePhabricator

D7655.id17291.diff
No OneTemporary

D7655.id17291.diff

Index: src/applications/doorkeeper/option/PhabricatorAsanaConfigOptions.php
===================================================================
--- src/applications/doorkeeper/option/PhabricatorAsanaConfigOptions.php
+++ src/applications/doorkeeper/option/PhabricatorAsanaConfigOptions.php
@@ -21,6 +21,16 @@
'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.'))
);
}
@@ -31,6 +41,8 @@
switch ($option->getKey()) {
case 'asana.workspace-id':
break;
+ case 'asana.project-ids':
+ return $this->renderContextualProjectDescription($option, $request);
default:
return parent::renderContextualDescription($option, $request);
}
@@ -89,5 +101,48 @@
$viewer);
}
+ private function renderContextualProjectDescription(
+ PhabricatorConfigOption $option,
+ AphrontRequest $request) {
+
+ $viewer = $request->getUser();
+
+ $publishers = id(new PhutilSymbolLoader())
+ ->setAncestorClass('DoorkeeperFeedStoryPublisher')
+ ->loadObjects();
+
+ $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);
+ }
}
Index: src/applications/doorkeeper/worker/DoorkeeperFeedWorkerAsana.php
===================================================================
--- src/applications/doorkeeper/worker/DoorkeeperFeedWorkerAsana.php
+++ src/applications/doorkeeper/worker/DoorkeeperFeedWorkerAsana.php
@@ -110,6 +110,8 @@
'assignee' => $owner_asana_id,
);
+ $projects = $this->getAsanaProjectIDs();
+
$extra_data = array();
if ($main_edge) {
$extra_data = $main_edge['data'];
@@ -164,6 +166,7 @@
'POST',
array(
'workspace' => $workspace_id,
+ 'projects' => $projects,
// NOTE: We initially create parent tasks in the "Later" state but
// don't update it afterward, even if the corresponding object
// becomes actionable. The expectation is that users will prioritize
@@ -214,6 +217,9 @@
if (empty($extra_data['gone'])) {
$this->addFollowers($oauth_token, $task_id, $silent_followers, true);
$this->addFollowers($oauth_token, $task_id, $noisy_followers);
+
+ // We're also going to synchronize project data here.
+ $this->addProjects($oauth_token, $task_id, $projects);
}
$dst_phid = $parent_ref->getExternalObject()->getPHID();
@@ -649,4 +655,37 @@
$data);
}
+ private function getAsanaProjectIDs() {
+ $project_ids = array();
+
+ $publisher = $this->getPublisher();
+ $config = PhabricatorEnv::getEnvConfig('asana.project-ids');
+ if (is_array($config)) {
+ $ids = idx($config, get_class($publisher));
+ if (is_array($ids)) {
+ foreach ($ids as $id) {
+ if (is_scalar($id)) {
+ $project_ids[] = $id;
+ }
+ }
+ }
+ }
+
+ return $project_ids;
+ }
+
+ private function addProjects(
+ $oauth_token,
+ $task_id,
+ array $project_ids) {
+ foreach ($project_ids as $project_id) {
+ $data = array('project' => $project_id);
+ $this->makeAsanaAPICall(
+ $oauth_token,
+ "tasks/{$task_id}/addProject",
+ 'POST',
+ $data);
+ }
+ }
+
}

File Metadata

Mime Type
text/plain
Expires
Fri, Sep 20, 9:29 AM (10 h, 24 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6623187
Default Alt Text
D7655.id17291.diff (4 KB)

Event Timeline