protected function applyRequest(ManiphestTask $task, ConduitAPIRequest $request, $is_new)
 {
     $changes = array();
     if ($is_new) {
         $task->setTitle((string) $request->getValue('title'));
         $task->setDescription((string) $request->getValue('description'));
         $changes[ManiphestTransaction::TYPE_STATUS] = ManiphestTaskStatus::getDefaultStatus();
         $changes[PhabricatorTransactions::TYPE_SUBSCRIBERS] = array('+' => array($request->getUser()->getPHID()));
     } else {
         $comments = $request->getValue('comments');
         if (!$is_new && $comments !== null) {
             $changes[PhabricatorTransactions::TYPE_COMMENT] = null;
         }
         $title = $request->getValue('title');
         if ($title !== null) {
             $changes[ManiphestTransaction::TYPE_TITLE] = $title;
         }
         $desc = $request->getValue('description');
         if ($desc !== null) {
             $changes[ManiphestTransaction::TYPE_DESCRIPTION] = $desc;
         }
         $status = $request->getValue('status');
         if ($status !== null) {
             $valid_statuses = ManiphestTaskStatus::getTaskStatusMap();
             if (!isset($valid_statuses[$status])) {
                 throw id(new ConduitException('ERR-INVALID-PARAMETER'))->setErrorDescription(pht('Status set to invalid value.'));
             }
             $changes[ManiphestTransaction::TYPE_STATUS] = $status;
         }
     }
     $priority = $request->getValue('priority');
     if ($priority !== null) {
         $valid_priorities = ManiphestTaskPriority::getTaskPriorityMap();
         if (!isset($valid_priorities[$priority])) {
             throw id(new ConduitException('ERR-INVALID-PARAMETER'))->setErrorDescription(pht('Priority set to invalid value.'));
         }
         $changes[ManiphestTransaction::TYPE_PRIORITY] = $priority;
     }
     $owner_phid = $request->getValue('ownerPHID');
     if ($owner_phid !== null) {
         $this->validatePHIDList(array($owner_phid), PhabricatorPeopleUserPHIDType::TYPECONST, 'ownerPHID');
         $changes[ManiphestTransaction::TYPE_OWNER] = $owner_phid;
     }
     $ccs = $request->getValue('ccPHIDs');
     if ($ccs !== null) {
         $changes[PhabricatorTransactions::TYPE_SUBSCRIBERS] = array('=' => array_fuse($ccs));
     }
     $transactions = array();
     $view_policy = $request->getValue('viewPolicy');
     if ($view_policy !== null) {
         $transactions[] = id(new ManiphestTransaction())->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)->setNewValue($view_policy);
     }
     $edit_policy = $request->getValue('editPolicy');
     if ($edit_policy !== null) {
         $transactions[] = id(new ManiphestTransaction())->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY)->setNewValue($edit_policy);
     }
     $project_phids = $request->getValue('projectPHIDs');
     if ($project_phids !== null) {
         $this->validatePHIDList($project_phids, PhabricatorProjectProjectPHIDType::TYPECONST, 'projectPHIDS');
         $project_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
         $transactions[] = id(new ManiphestTransaction())->setTransactionType(PhabricatorTransactions::TYPE_EDGE)->setMetadataValue('edge:type', $project_type)->setNewValue(array('=' => array_fuse($project_phids)));
     }
     $template = new ManiphestTransaction();
     foreach ($changes as $type => $value) {
         $transaction = clone $template;
         $transaction->setTransactionType($type);
         if ($type == PhabricatorTransactions::TYPE_COMMENT) {
             $transaction->attachComment(id(new ManiphestTransactionComment())->setContent($comments));
         } else {
             $transaction->setNewValue($value);
         }
         $transactions[] = $transaction;
     }
     $field_list = PhabricatorCustomField::getObjectFields($task, PhabricatorCustomField::ROLE_EDIT);
     $field_list->readFieldsFromStorage($task);
     $auxiliary = $request->getValue('auxiliary');
     if ($auxiliary) {
         foreach ($field_list->getFields() as $key => $field) {
             if (!array_key_exists($key, $auxiliary)) {
                 continue;
             }
             $transaction = clone $template;
             $transaction->setTransactionType(PhabricatorTransactions::TYPE_CUSTOMFIELD);
             $transaction->setMetadataValue('customfield:key', $key);
             $transaction->setOldValue($field->getOldValueForApplicationTransactions());
             $transaction->setNewValue($auxiliary[$key]);
             $transactions[] = $transaction;
         }
     }
     if (!$transactions) {
         return;
     }
     $event = new PhabricatorEvent(PhabricatorEventType::TYPE_MANIPHEST_WILLEDITTASK, array('task' => $task, 'new' => $is_new, 'transactions' => $transactions));
     $event->setUser($request->getUser());
     $event->setConduitRequest($request);
     PhutilEventEngine::dispatchEvent($event);
     $task = $event->getValue('task');
     $transactions = $event->getValue('transactions');
     $content_source = PhabricatorContentSource::newForSource(PhabricatorContentSource::SOURCE_CONDUIT, array());
     $editor = id(new ManiphestTransactionEditor())->setActor($request->getUser())->setContentSource($content_source)->setContinueOnNoEffect(true);
     if (!$is_new) {
         $editor->setContinueOnMissingFields(true);
     }
     $editor->applyTransactions($task, $transactions);
     $event = new PhabricatorEvent(PhabricatorEventType::TYPE_MANIPHEST_DIDEDITTASK, array('task' => $task, 'new' => $is_new, 'transactions' => $transactions));
     $event->setUser($request->getUser());
     $event->setConduitRequest($request);
     PhutilEventEngine::dispatchEvent($event);
     // reload the task now that we've done all the fun stuff
     return id(new ManiphestTaskQuery())->setViewer($request->getUser())->withPHIDs(array($task->getPHID()))->needSubscriberPHIDs(true)->needProjectPHIDs(true)->executeOne();
 }
 protected function applyRequest(ManiphestTask $task, ConduitAPIRequest $request, $is_new)
 {
     $changes = array();
     if ($is_new) {
         $task->setTitle((string) $request->getValue('title'));
         $task->setDescription((string) $request->getValue('description'));
         $changes[ManiphestTransactionType::TYPE_STATUS] = ManiphestTaskStatus::STATUS_OPEN;
     } else {
         $comments = $request->getValue('comments');
         if (!$is_new && $comments !== null) {
             $changes[ManiphestTransactionType::TYPE_NONE] = null;
         }
         $title = $request->getValue('title');
         if ($title !== null) {
             $changes[ManiphestTransactionType::TYPE_TITLE] = $title;
         }
         $desc = $request->getValue('description');
         if ($desc !== null) {
             $changes[ManiphestTransactionType::TYPE_DESCRIPTION] = $desc;
         }
         $status = $request->getValue('status');
         if ($status !== null) {
             $valid_statuses = ManiphestTaskStatus::getTaskStatusMap();
             if (!isset($valid_statuses[$status])) {
                 throw id(new ConduitException('ERR-INVALID-PARAMETER'))->setErrorDescription('Status set to invalid value.');
             }
             $changes[ManiphestTransactionType::TYPE_STATUS] = $status;
         }
     }
     $priority = $request->getValue('priority');
     if ($priority !== null) {
         $valid_priorities = ManiphestTaskPriority::getTaskPriorityMap();
         if (!isset($valid_priorities[$priority])) {
             throw id(new ConduitException('ERR-INVALID-PARAMETER'))->setErrorDescription('Priority set to invalid value.');
         }
         $changes[ManiphestTransactionType::TYPE_PRIORITY] = $priority;
     }
     $owner_phid = $request->getValue('ownerPHID');
     if ($owner_phid !== null) {
         $this->validatePHIDList(array($owner_phid), PhabricatorPHIDConstants::PHID_TYPE_USER, 'ownerPHID');
         $changes[ManiphestTransactionType::TYPE_OWNER] = $owner_phid;
     }
     $ccs = $request->getValue('ccPHIDs');
     if ($ccs !== null) {
         $this->validatePHIDList($ccs, PhabricatorPHIDConstants::PHID_TYPE_USER, 'ccPHIDS');
         $changes[ManiphestTransactionType::TYPE_CCS] = $ccs;
     }
     $project_phids = $request->getValue('projectPHIDs');
     if ($project_phids !== null) {
         $this->validatePHIDList($project_phids, PhabricatorPHIDConstants::PHID_TYPE_PROJ, 'projectPHIDS');
         $changes[ManiphestTransactionType::TYPE_PROJECTS] = $project_phids;
     }
     $file_phids = $request->getValue('filePHIDs');
     if ($file_phids !== null) {
         $this->validatePHIDList($file_phids, PhabricatorPHIDConstants::PHID_TYPE_FILE, 'filePHIDS');
         $file_map = array_fill_keys($file_phids, true);
         $attached = $task->getAttached();
         $attached[PhabricatorPHIDConstants::PHID_TYPE_FILE] = $file_map;
         $changes[ManiphestTransactionType::TYPE_ATTACH] = $attached;
     }
     $content_source = PhabricatorContentSource::newForSource(PhabricatorContentSource::SOURCE_CONDUIT, array());
     $template = new ManiphestTransaction();
     $template->setContentSource($content_source);
     $template->setAuthorPHID($request->getUser()->getPHID());
     $transactions = array();
     foreach ($changes as $type => $value) {
         $transaction = clone $template;
         $transaction->setTransactionType($type);
         $transaction->setNewValue($value);
         if ($type == ManiphestTransactionType::TYPE_NONE) {
             $transaction->setComments($comments);
         }
         $transactions[] = $transaction;
     }
     $auxiliary = $request->getValue('auxiliary');
     if ($auxiliary) {
         $task->loadAndAttachAuxiliaryAttributes();
         foreach ($auxiliary as $aux_key => $aux_value) {
             $transaction = clone $template;
             $transaction->setTransactionType(ManiphestTransactionType::TYPE_AUXILIARY);
             $transaction->setMetadataValue('aux:key', $aux_key);
             $transaction->setNewValue($aux_value);
             $transactions[] = $transaction;
         }
     }
     $event = new PhabricatorEvent(PhabricatorEventType::TYPE_MANIPHEST_WILLEDITTASK, array('task' => $task, 'new' => $is_new, 'transactions' => $transactions));
     $event->setUser($request->getUser());
     $event->setConduitRequest($request);
     PhutilEventEngine::dispatchEvent($event);
     $task = $event->getValue('task');
     $transactions = $event->getValue('transactions');
     $editor = new ManiphestTransactionEditor();
     $editor->applyTransactions($task, $transactions);
     $event = new PhabricatorEvent(PhabricatorEventType::TYPE_MANIPHEST_DIDEDITTASK, array('task' => $task, 'new' => $is_new, 'transactions' => $transactions));
     $event->setUser($request->getUser());
     $event->setConduitRequest($request);
     PhutilEventEngine::dispatchEvent($event);
 }