[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 abstract class ManiphestConduitAPIMethod extends ConduitAPIMethod { 4 5 final public function getApplication() { 6 return PhabricatorApplication::getByClass( 7 'PhabricatorManiphestApplication'); 8 } 9 10 public function defineErrorTypes() { 11 return array( 12 'ERR-INVALID-PARAMETER' => 'Missing or malformed parameter.', 13 ); 14 } 15 16 protected function buildTaskInfoDictionary(ManiphestTask $task) { 17 $results = $this->buildTaskInfoDictionaries(array($task)); 18 return idx($results, $task->getPHID()); 19 } 20 21 protected function getTaskFields($is_new) { 22 $fields = array(); 23 24 if (!$is_new) { 25 $fields += array( 26 'id' => 'optional int', 27 'phid' => 'optional int', 28 ); 29 } 30 31 $fields += array( 32 'title' => $is_new ? 'required string' : 'optional string', 33 'description' => 'optional string', 34 'ownerPHID' => 'optional phid', 35 'viewPolicy' => 'optional phid or policy string', 36 'editPolicy' => 'optional phid or policy string', 37 'ccPHIDs' => 'optional list<phid>', 38 'priority' => 'optional int', 39 'projectPHIDs' => 'optional list<phid>', 40 'auxiliary' => 'optional dict', 41 ); 42 43 if (!$is_new) { 44 $fields += array( 45 'status' => 'optional string', 46 'comments' => 'optional string', 47 ); 48 } 49 50 return $fields; 51 } 52 53 protected function applyRequest( 54 ManiphestTask $task, 55 ConduitAPIRequest $request, 56 $is_new) { 57 58 $changes = array(); 59 60 if ($is_new) { 61 $task->setTitle((string)$request->getValue('title')); 62 $task->setDescription((string)$request->getValue('description')); 63 $changes[ManiphestTransaction::TYPE_STATUS] = 64 ManiphestTaskStatus::getDefaultStatus(); 65 } else { 66 67 $comments = $request->getValue('comments'); 68 if (!$is_new && $comments !== null) { 69 $changes[PhabricatorTransactions::TYPE_COMMENT] = null; 70 } 71 72 $title = $request->getValue('title'); 73 if ($title !== null) { 74 $changes[ManiphestTransaction::TYPE_TITLE] = $title; 75 } 76 77 $desc = $request->getValue('description'); 78 if ($desc !== null) { 79 $changes[ManiphestTransaction::TYPE_DESCRIPTION] = $desc; 80 } 81 82 $status = $request->getValue('status'); 83 if ($status !== null) { 84 $valid_statuses = ManiphestTaskStatus::getTaskStatusMap(); 85 if (!isset($valid_statuses[$status])) { 86 throw id(new ConduitException('ERR-INVALID-PARAMETER')) 87 ->setErrorDescription('Status set to invalid value.'); 88 } 89 $changes[ManiphestTransaction::TYPE_STATUS] = $status; 90 } 91 } 92 93 $priority = $request->getValue('priority'); 94 if ($priority !== null) { 95 $valid_priorities = ManiphestTaskPriority::getTaskPriorityMap(); 96 if (!isset($valid_priorities[$priority])) { 97 throw id(new ConduitException('ERR-INVALID-PARAMETER')) 98 ->setErrorDescription('Priority set to invalid value.'); 99 } 100 $changes[ManiphestTransaction::TYPE_PRIORITY] = $priority; 101 } 102 103 $owner_phid = $request->getValue('ownerPHID'); 104 if ($owner_phid !== null) { 105 $this->validatePHIDList( 106 array($owner_phid), 107 PhabricatorPeopleUserPHIDType::TYPECONST, 108 'ownerPHID'); 109 $changes[ManiphestTransaction::TYPE_OWNER] = $owner_phid; 110 } 111 112 $ccs = $request->getValue('ccPHIDs'); 113 if ($ccs !== null) { 114 $changes[ManiphestTransaction::TYPE_CCS] = $ccs; 115 } 116 117 $transactions = array(); 118 119 $view_policy = $request->getValue('viewPolicy'); 120 if ($view_policy !== null) { 121 $transactions[] = id(new ManiphestTransaction()) 122 ->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY) 123 ->setNewValue($view_policy); 124 } 125 126 $edit_policy = $request->getValue('editPolicy'); 127 if ($edit_policy !== null) { 128 $transactions[] = id(new ManiphestTransaction()) 129 ->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY) 130 ->setNewValue($edit_policy); 131 } 132 133 $project_phids = $request->getValue('projectPHIDs'); 134 if ($project_phids !== null) { 135 $this->validatePHIDList( 136 $project_phids, 137 PhabricatorProjectProjectPHIDType::TYPECONST, 138 'projectPHIDS'); 139 140 $project_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST; 141 $transactions[] = id(new ManiphestTransaction()) 142 ->setTransactionType(PhabricatorTransactions::TYPE_EDGE) 143 ->setMetadataValue('edge:type', $project_type) 144 ->setNewValue( 145 array( 146 '=' => array_fuse($project_phids), 147 )); 148 } 149 150 $template = new ManiphestTransaction(); 151 152 foreach ($changes as $type => $value) { 153 $transaction = clone $template; 154 $transaction->setTransactionType($type); 155 if ($type == PhabricatorTransactions::TYPE_COMMENT) { 156 $transaction->attachComment( 157 id(new ManiphestTransactionComment()) 158 ->setContent($comments)); 159 } else { 160 $transaction->setNewValue($value); 161 } 162 163 $transactions[] = $transaction; 164 } 165 166 $field_list = PhabricatorCustomField::getObjectFields( 167 $task, 168 PhabricatorCustomField::ROLE_EDIT); 169 $field_list->readFieldsFromStorage($task); 170 171 $auxiliary = $request->getValue('auxiliary'); 172 if ($auxiliary) { 173 foreach ($field_list->getFields() as $key => $field) { 174 if (!array_key_exists($key, $auxiliary)) { 175 continue; 176 } 177 $transaction = clone $template; 178 $transaction->setTransactionType( 179 PhabricatorTransactions::TYPE_CUSTOMFIELD); 180 $transaction->setMetadataValue('customfield:key', $key); 181 $transaction->setOldValue( 182 $field->getOldValueForApplicationTransactions()); 183 $transaction->setNewValue($auxiliary[$key]); 184 $transactions[] = $transaction; 185 } 186 } 187 188 if (!$transactions) { 189 return; 190 } 191 192 $event = new PhabricatorEvent( 193 PhabricatorEventType::TYPE_MANIPHEST_WILLEDITTASK, 194 array( 195 'task' => $task, 196 'new' => $is_new, 197 'transactions' => $transactions, 198 )); 199 $event->setUser($request->getUser()); 200 $event->setConduitRequest($request); 201 PhutilEventEngine::dispatchEvent($event); 202 203 $task = $event->getValue('task'); 204 $transactions = $event->getValue('transactions'); 205 206 $content_source = PhabricatorContentSource::newForSource( 207 PhabricatorContentSource::SOURCE_CONDUIT, 208 array()); 209 210 $editor = id(new ManiphestTransactionEditor()) 211 ->setActor($request->getUser()) 212 ->setContentSource($content_source) 213 ->setContinueOnNoEffect(true); 214 215 if (!$is_new) { 216 $editor->setContinueOnMissingFields(true); 217 } 218 219 $editor->applyTransactions($task, $transactions); 220 221 $event = new PhabricatorEvent( 222 PhabricatorEventType::TYPE_MANIPHEST_DIDEDITTASK, 223 array( 224 'task' => $task, 225 'new' => $is_new, 226 'transactions' => $transactions, 227 )); 228 $event->setUser($request->getUser()); 229 $event->setConduitRequest($request); 230 PhutilEventEngine::dispatchEvent($event); 231 } 232 233 protected function buildTaskInfoDictionaries(array $tasks) { 234 assert_instances_of($tasks, 'ManiphestTask'); 235 if (!$tasks) { 236 return array(); 237 } 238 239 $task_phids = mpull($tasks, 'getPHID'); 240 241 $all_deps = id(new PhabricatorEdgeQuery()) 242 ->withSourcePHIDs($task_phids) 243 ->withEdgeTypes(array(PhabricatorEdgeConfig::TYPE_TASK_DEPENDS_ON_TASK)); 244 $all_deps->execute(); 245 246 $result = array(); 247 foreach ($tasks as $task) { 248 // TODO: Batch this get as CustomField gets cleaned up. 249 $field_list = PhabricatorCustomField::getObjectFields( 250 $task, 251 PhabricatorCustomField::ROLE_EDIT); 252 $field_list->readFieldsFromStorage($task); 253 254 $auxiliary = mpull( 255 $field_list->getFields(), 256 'getValueForStorage', 257 'getFieldKey'); 258 259 $task_deps = $all_deps->getDestinationPHIDs( 260 array($task->getPHID()), 261 array(PhabricatorEdgeConfig::TYPE_TASK_DEPENDS_ON_TASK)); 262 263 $result[$task->getPHID()] = array( 264 'id' => $task->getID(), 265 'phid' => $task->getPHID(), 266 'authorPHID' => $task->getAuthorPHID(), 267 'ownerPHID' => $task->getOwnerPHID(), 268 'ccPHIDs' => $task->getCCPHIDs(), 269 'status' => $task->getStatus(), 270 'statusName' => ManiphestTaskStatus::getTaskStatusName( 271 $task->getStatus()), 272 'isClosed' => $task->isClosed(), 273 'priority' => ManiphestTaskPriority::getTaskPriorityName( 274 $task->getPriority()), 275 'priorityColor' => ManiphestTaskPriority::getTaskPriorityColor( 276 $task->getPriority()), 277 'title' => $task->getTitle(), 278 'description' => $task->getDescription(), 279 'projectPHIDs' => $task->getProjectPHIDs(), 280 'uri' => PhabricatorEnv::getProductionURI('/T'.$task->getID()), 281 'auxiliary' => $auxiliary, 282 283 'objectName' => 'T'.$task->getID(), 284 'dateCreated' => $task->getDateCreated(), 285 'dateModified' => $task->getDateModified(), 286 'dependsOnTaskPHIDs' => $task_deps, 287 ); 288 } 289 290 return $result; 291 } 292 293 /** 294 * NOTE: This is a temporary stop gap since its easy to make malformed tasks. 295 * Long-term, the values set in @{method:defineParamTypes} will be used to 296 * validate data implicitly within the larger Conduit application. 297 * 298 * TODO: Remove this in favor of generalized Conduit hotness. 299 */ 300 private function validatePHIDList(array $phid_list, $phid_type, $field) { 301 $phid_groups = phid_group_by_type($phid_list); 302 unset($phid_groups[$phid_type]); 303 if (!empty($phid_groups)) { 304 throw id(new ConduitException('ERR-INVALID-PARAMETER')) 305 ->setErrorDescription('One or more PHIDs were invalid for '.$field.'.'); 306 } 307 308 return true; 309 } 310 311 }
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 |