public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $comments = $request->getStr('comments');
     $task = id(new ManiphestTask())->load($this->id);
     if (!$task) {
         return new Aphront404Response();
     }
     $draft = id(new PhabricatorDraft())->loadOneWhere('authorPHID = %s AND draftKey = %s', $user->getPHID(), $task->getPHID());
     if (!$draft) {
         $draft = new PhabricatorDraft();
         $draft->setAuthorPHID($user->getPHID());
         $draft->setDraftKey($task->getPHID());
     }
     $draft->setDraft($comments);
     $draft->save();
     $phids = array($user->getPHID());
     $action = $request->getStr('action');
     $transaction = new ManiphestTransaction();
     $transaction->setAuthorPHID($user->getPHID());
     $transaction->setComments($comments);
     $transaction->setTransactionType($action);
     $value = $request->getStr('value');
     switch ($action) {
         case ManiphestTransactionType::TYPE_OWNER:
             if (!$value) {
                 $value = $user->getPHID();
             }
             $phids[] = $value;
             break;
         case ManiphestTransactionType::TYPE_PRIORITY:
             $transaction->setOldValue($task->getPriority());
             break;
     }
     $transaction->setNewValue($value);
     $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
     $transactions = array();
     $transactions[] = $transaction;
     $engine = PhabricatorMarkupEngine::newManiphestMarkupEngine();
     $transaction_view = new ManiphestTransactionListView();
     $transaction_view->setTransactions($transactions);
     $transaction_view->setHandles($handles);
     $transaction_view->setUser($user);
     $transaction_view->setMarkupEngine($engine);
     $transaction_view->setPreview(true);
     return id(new AphrontAjaxResponse())->setContent($transaction_view->render());
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $comments = $request->getStr('comments');
     $task = id(new ManiphestTask())->load($this->id);
     if (!$task) {
         return new Aphront404Response();
     }
     $draft = id(new PhabricatorDraft())->loadOneWhere('authorPHID = %s AND draftKey = %s', $user->getPHID(), $task->getPHID());
     if (!$draft) {
         $draft = new PhabricatorDraft();
         $draft->setAuthorPHID($user->getPHID());
         $draft->setDraftKey($task->getPHID());
     }
     $draft->setDraft($comments);
     $draft->save();
     $action = $request->getStr('action');
     $transaction = new ManiphestTransaction();
     $transaction->setAuthorPHID($user->getPHID());
     $transaction->setComments($comments);
     $transaction->setTransactionType($action);
     $value = $request->getStr('value');
     // grab phids for handles and set transaction values based on action and
     // value (empty or control-specific format) coming in from the wire
     switch ($action) {
         case ManiphestTransactionType::TYPE_PRIORITY:
             $transaction->setOldValue($task->getPriority());
             $transaction->setNewValue($value);
             break;
         case ManiphestTransactionType::TYPE_OWNER:
             if ($value) {
                 $value = current(json_decode($value));
                 $phids = array($value);
             } else {
                 $phids = array();
             }
             $transaction->setNewValue($value);
             break;
         case ManiphestTransactionType::TYPE_CCS:
             if ($value) {
                 $value = json_decode($value);
                 $phids = $value;
                 foreach ($task->getCCPHIDs() as $cc_phid) {
                     $phids[] = $cc_phid;
                     $value[] = $cc_phid;
                 }
                 $transaction->setNewValue($value);
             } else {
                 $phids = array();
                 $transaction->setNewValue(array());
             }
             $transaction->setOldValue($task->getCCPHIDs());
             break;
         case ManiphestTransactionType::TYPE_PROJECTS:
             if ($value) {
                 $value = json_decode($value);
                 $phids = $value;
                 foreach ($task->getProjectPHIDs() as $project_phid) {
                     $phids[] = $project_phid;
                     $value[] = $project_phid;
                 }
                 $transaction->setNewValue($value);
             } else {
                 $phids = array();
                 $transaction->setNewValue(array());
             }
             $transaction->setOldValue($task->getProjectPHIDs());
             break;
         default:
             $phids = array();
             $transaction->setNewValue($value);
             break;
     }
     $phids[] = $user->getPHID();
     $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
     $transactions = array();
     $transactions[] = $transaction;
     $engine = new PhabricatorMarkupEngine();
     $engine->addObject($transaction, ManiphestTransaction::MARKUP_FIELD_BODY);
     $engine->process();
     $transaction_view = new ManiphestTransactionListView();
     $transaction_view->setTransactions($transactions);
     $transaction_view->setHandles($handles);
     $transaction_view->setUser($user);
     $transaction_view->setMarkupEngine($engine);
     $transaction_view->setPreview(true);
     return id(new AphrontAjaxResponse())->setContent($transaction_view->render());
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $e_title = null;
     $priority_map = ManiphestTaskPriority::getTaskPriorityMap();
     $task = id(new ManiphestTask())->load($this->id);
     if (!$task) {
         return new Aphront404Response();
     }
     $workflow = $request->getStr('workflow');
     $parent_task = null;
     if ($workflow && is_numeric($workflow)) {
         $parent_task = id(new ManiphestTask())->load($workflow);
     }
     $transactions = id(new ManiphestTransaction())->loadAllWhere('taskID = %d ORDER BY id ASC', $task->getID());
     $e_commit = PhabricatorEdgeConfig::TYPE_TASK_HAS_COMMIT;
     $e_dep_on = PhabricatorEdgeConfig::TYPE_TASK_DEPENDS_ON_TASK;
     $e_dep_by = PhabricatorEdgeConfig::TYPE_TASK_DEPENDED_ON_BY_TASK;
     $e_rev = PhabricatorEdgeConfig::TYPE_TASK_HAS_RELATED_DREV;
     $phid = $task->getPHID();
     $query = id(new PhabricatorEdgeQuery())->withSourcePHIDs(array($phid))->withEdgeTypes(array($e_commit, $e_dep_on, $e_dep_by, $e_rev));
     $edges = $query->execute();
     $commit_phids = array_keys($edges[$phid][$e_commit]);
     $dep_on_tasks = array_keys($edges[$phid][$e_dep_on]);
     $dep_by_tasks = array_keys($edges[$phid][$e_dep_by]);
     $revs = array_keys($edges[$phid][$e_rev]);
     $phids = array_fill_keys($query->getDestinationPHIDs(), true);
     foreach ($transactions as $transaction) {
         foreach ($transaction->extractPHIDs() as $phid) {
             $phids[$phid] = true;
         }
     }
     foreach ($task->getCCPHIDs() as $phid) {
         $phids[$phid] = true;
     }
     foreach ($task->getProjectPHIDs() as $phid) {
         $phids[$phid] = true;
     }
     if ($task->getOwnerPHID()) {
         $phids[$task->getOwnerPHID()] = true;
     }
     $phids[$task->getAuthorPHID()] = true;
     $attached = $task->getAttached();
     foreach ($attached as $type => $list) {
         foreach ($list as $phid => $info) {
             $phids[$phid] = true;
         }
     }
     if ($parent_task) {
         $phids[$parent_task->getPHID()] = true;
     }
     $phids = array_keys($phids);
     $handles = $this->loadViewerHandles($phids);
     $dict = array();
     $dict['Status'] = '<strong>' . ManiphestTaskStatus::getTaskStatusFullName($task->getStatus()) . '</strong>';
     $dict['Assigned To'] = $task->getOwnerPHID() ? $handles[$task->getOwnerPHID()]->renderLink() : '<em>None</em>';
     $dict['Priority'] = ManiphestTaskPriority::getTaskPriorityName($task->getPriority());
     $cc = $task->getCCPHIDs();
     if ($cc) {
         $cc_links = array();
         foreach ($cc as $phid) {
             $cc_links[] = $handles[$phid]->renderLink();
         }
         $dict['CC'] = implode(', ', $cc_links);
     } else {
         $dict['CC'] = '<em>None</em>';
     }
     $dict['Author'] = $handles[$task->getAuthorPHID()]->renderLink();
     $source = $task->getOriginalEmailSource();
     if ($source) {
         $subject = '[T' . $task->getID() . '] ' . $task->getTitle();
         $dict['From Email'] = phutil_render_tag('a', array('href' => 'mailto:' . $source . '?subject=' . $subject), phutil_escape_html($source));
     }
     $projects = $task->getProjectPHIDs();
     if ($projects) {
         $project_links = array();
         foreach ($projects as $phid) {
             $project_links[] = $handles[$phid]->renderLink();
         }
         $dict['Projects'] = implode(', ', $project_links);
     } else {
         $dict['Projects'] = '<em>None</em>';
     }
     $extensions = ManiphestTaskExtensions::newExtensions();
     $aux_fields = $extensions->getAuxiliaryFieldSpecifications();
     if ($aux_fields) {
         $task->loadAndAttachAuxiliaryAttributes();
         foreach ($aux_fields as $aux_field) {
             $aux_key = $aux_field->getAuxiliaryKey();
             $aux_field->setValue($task->getAuxiliaryAttribute($aux_key));
             $value = $aux_field->renderForDetailView();
             if (strlen($value)) {
                 $dict[$aux_field->getLabel()] = $value;
             }
         }
     }
     if ($dep_by_tasks) {
         $dict['Dependent Tasks'] = $this->renderHandleList(array_select_keys($handles, $dep_by_tasks));
     }
     if ($dep_on_tasks) {
         $dict['Depends On'] = $this->renderHandleList(array_select_keys($handles, $dep_on_tasks));
     }
     if ($revs) {
         $dict['Revisions'] = $this->renderHandleList(array_select_keys($handles, $revs));
     }
     if ($commit_phids) {
         $dict['Commits'] = $this->renderHandleList(array_select_keys($handles, $commit_phids));
     }
     $file_infos = idx($attached, PhabricatorPHIDConstants::PHID_TYPE_FILE);
     if ($file_infos) {
         $file_phids = array_keys($file_infos);
         $files = id(new PhabricatorFile())->loadAllWhere('phid IN (%Ls)', $file_phids);
         $views = array();
         foreach ($files as $file) {
             $view = new AphrontFilePreviewView();
             $view->setFile($file);
             $views[] = $view->render();
         }
         $dict['Files'] = implode('', $views);
     }
     $context_bar = null;
     if ($parent_task) {
         $context_bar = new AphrontContextBarView();
         $context_bar->addButton(phutil_render_tag('a', array('href' => '/maniphest/task/create/?parent=' . $parent_task->getID(), 'class' => 'green button'), 'Create Another Subtask'));
         $context_bar->appendChild('Created a subtask of <strong>' . $handles[$parent_task->getPHID()]->renderLink() . '</strong>');
     } else {
         if ($workflow == 'create') {
             $context_bar = new AphrontContextBarView();
             $context_bar->addButton('<label>Create Another:</label>');
             $context_bar->addButton(phutil_render_tag('a', array('href' => '/maniphest/task/create/?template=' . $task->getID(), 'class' => 'green button'), 'Similar Task'));
             $context_bar->addButton(phutil_render_tag('a', array('href' => '/maniphest/task/create/', 'class' => 'green button'), 'Empty Task'));
             $context_bar->appendChild('New task created.');
         }
     }
     $actions = array();
     $action = new AphrontHeadsupActionView();
     $action->setName('Edit Task');
     $action->setURI('/maniphest/task/edit/' . $task->getID() . '/');
     $action->setClass('action-edit');
     $actions[] = $action;
     require_celerity_resource('phabricator-flag-css');
     $flag = PhabricatorFlagQuery::loadUserFlag($user, $task->getPHID());
     if ($flag) {
         $class = PhabricatorFlagColor::getCSSClass($flag->getColor());
         $color = PhabricatorFlagColor::getColorName($flag->getColor());
         $action = new AphrontHeadsupActionView();
         $action->setClass('flag-clear ' . $class);
         $action->setURI('/flag/delete/' . $flag->getID() . '/');
         $action->setName('Remove ' . $color . ' Flag');
         $action->setWorkflow(true);
         $actions[] = $action;
     } else {
         $action = new AphrontHeadsupActionView();
         $action->setClass('phabricator-flag-ghost');
         $action->setURI('/flag/edit/' . $task->getPHID() . '/');
         $action->setName('Flag Task');
         $action->setWorkflow(true);
         $actions[] = $action;
     }
     require_celerity_resource('phabricator-object-selector-css');
     require_celerity_resource('javelin-behavior-phabricator-object-selector');
     $action = new AphrontHeadsupActionView();
     $action->setName('Merge Duplicates');
     $action->setURI('/search/attach/' . $task->getPHID() . '/TASK/merge/');
     $action->setWorkflow(true);
     $action->setClass('action-merge');
     $actions[] = $action;
     $action = new AphrontHeadsupActionView();
     $action->setName('Create Subtask');
     $action->setURI('/maniphest/task/create/?parent=' . $task->getID());
     $action->setClass('action-branch');
     $actions[] = $action;
     $action = new AphrontHeadsupActionView();
     $action->setName('Edit Dependencies');
     $action->setURI('/search/attach/' . $task->getPHID() . '/TASK/dependencies/');
     $action->setWorkflow(true);
     $action->setClass('action-dependencies');
     $actions[] = $action;
     $action = new AphrontHeadsupActionView();
     $action->setName('Edit Differential Revisions');
     $action->setURI('/search/attach/' . $task->getPHID() . '/DREV/');
     $action->setWorkflow(true);
     $action->setClass('action-attach');
     $actions[] = $action;
     $action_list = new AphrontHeadsupActionListView();
     $action_list->setActions($actions);
     $headsup_panel = new AphrontHeadsupView();
     $headsup_panel->setObjectName('T' . $task->getID());
     $headsup_panel->setHeader($task->getTitle());
     $headsup_panel->setActionList($action_list);
     $headsup_panel->setProperties($dict);
     $engine = new PhabricatorMarkupEngine();
     $engine->setViewer($user);
     $engine->addObject($task, ManiphestTask::MARKUP_FIELD_DESCRIPTION);
     foreach ($transactions as $xaction) {
         if ($xaction->hasComments()) {
             $engine->addObject($xaction, ManiphestTransaction::MARKUP_FIELD_BODY);
         }
     }
     $engine->process();
     $headsup_panel->appendChild('<div class="phabricator-remarkup">' . $engine->getOutput($task, ManiphestTask::MARKUP_FIELD_DESCRIPTION) . '</div>');
     $transaction_types = ManiphestTransactionType::getTransactionTypeMap();
     $resolution_types = ManiphestTaskStatus::getTaskStatusMap();
     if ($task->getStatus() == ManiphestTaskStatus::STATUS_OPEN) {
         $resolution_types = array_select_keys($resolution_types, array(ManiphestTaskStatus::STATUS_CLOSED_RESOLVED, ManiphestTaskStatus::STATUS_CLOSED_WONTFIX, ManiphestTaskStatus::STATUS_CLOSED_INVALID, ManiphestTaskStatus::STATUS_CLOSED_SPITE));
     } else {
         $resolution_types = array(ManiphestTaskStatus::STATUS_OPEN => 'Reopened');
         $transaction_types[ManiphestTransactionType::TYPE_STATUS] = 'Reopen Task';
         unset($transaction_types[ManiphestTransactionType::TYPE_PRIORITY]);
         unset($transaction_types[ManiphestTransactionType::TYPE_OWNER]);
     }
     $default_claim = array($user->getPHID() => $user->getUsername() . ' (' . $user->getRealName() . ')');
     $draft = id(new PhabricatorDraft())->loadOneWhere('authorPHID = %s AND draftKey = %s', $user->getPHID(), $task->getPHID());
     if ($draft) {
         $draft_text = $draft->getDraft();
     } else {
         $draft_text = null;
     }
     $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
     if ($is_serious) {
         // Prevent tasks from being closed "out of spite" in serious business
         // installs.
         unset($resolution_types[ManiphestTaskStatus::STATUS_CLOSED_SPITE]);
     }
     $comment_form = new AphrontFormView();
     $comment_form->setUser($user)->setAction('/maniphest/transaction/save/')->setEncType('multipart/form-data')->addHiddenInput('taskID', $task->getID())->appendChild(id(new AphrontFormSelectControl())->setLabel('Action')->setName('action')->setOptions($transaction_types)->setID('transaction-action'))->appendChild(id(new AphrontFormSelectControl())->setLabel('Resolution')->setName('resolution')->setControlID('resolution')->setControlStyle('display: none')->setOptions($resolution_types))->appendChild(id(new AphrontFormTokenizerControl())->setLabel('Assign To')->setName('assign_to')->setControlID('assign_to')->setControlStyle('display: none')->setID('assign-tokenizer')->setDisableBehavior(true))->appendChild(id(new AphrontFormTokenizerControl())->setLabel('CCs')->setName('ccs')->setControlID('ccs')->setControlStyle('display: none')->setID('cc-tokenizer')->setDisableBehavior(true))->appendChild(id(new AphrontFormSelectControl())->setLabel('Priority')->setName('priority')->setOptions($priority_map)->setControlID('priority')->setControlStyle('display: none')->setValue($task->getPriority()))->appendChild(id(new AphrontFormTokenizerControl())->setLabel('Projects')->setName('projects')->setControlID('projects')->setControlStyle('display: none')->setID('projects-tokenizer')->setDisableBehavior(true))->appendChild(id(new AphrontFormFileControl())->setLabel('File')->setName('file')->setControlID('file')->setControlStyle('display: none'))->appendChild(id(new PhabricatorRemarkupControl())->setLabel('Comments')->setName('comments')->setValue($draft_text)->setID('transaction-comments'))->appendChild(id(new AphrontFormDragAndDropUploadControl())->setLabel('Attached Files')->setName('files')->setActivatedClass('aphront-panel-view-drag-and-drop'))->appendChild(id(new AphrontFormSubmitControl())->setValue($is_serious ? 'Submit' : 'Avast!'));
     $control_map = array(ManiphestTransactionType::TYPE_STATUS => 'resolution', ManiphestTransactionType::TYPE_OWNER => 'assign_to', ManiphestTransactionType::TYPE_CCS => 'ccs', ManiphestTransactionType::TYPE_PRIORITY => 'priority', ManiphestTransactionType::TYPE_PROJECTS => 'projects', ManiphestTransactionType::TYPE_ATTACH => 'file');
     $tokenizer_map = array(ManiphestTransactionType::TYPE_PROJECTS => array('id' => 'projects-tokenizer', 'src' => '/typeahead/common/projects/', 'ondemand' => PhabricatorEnv::getEnvConfig('tokenizer.ondemand'), 'placeholder' => 'Type a project name...'), ManiphestTransactionType::TYPE_OWNER => array('id' => 'assign-tokenizer', 'src' => '/typeahead/common/users/', 'value' => $default_claim, 'limit' => 1, 'ondemand' => PhabricatorEnv::getEnvConfig('tokenizer.ondemand'), 'placeholder' => 'Type a user name...'), ManiphestTransactionType::TYPE_CCS => array('id' => 'cc-tokenizer', 'src' => '/typeahead/common/mailable/', 'ondemand' => PhabricatorEnv::getEnvConfig('tokenizer.ondemand'), 'placeholder' => 'Type a user or mailing list...'));
     Javelin::initBehavior('maniphest-transaction-controls', array('select' => 'transaction-action', 'controlMap' => $control_map, 'tokenizers' => $tokenizer_map));
     Javelin::initBehavior('maniphest-transaction-preview', array('uri' => '/maniphest/transaction/preview/' . $task->getID() . '/', 'preview' => 'transaction-preview', 'comments' => 'transaction-comments', 'action' => 'transaction-action', 'map' => $control_map, 'tokenizers' => $tokenizer_map));
     $comment_panel = new AphrontPanelView();
     $comment_panel->appendChild($comment_form);
     $comment_panel->addClass('aphront-panel-accent');
     $comment_panel->setHeader($is_serious ? 'Add Comment' : 'Weigh In');
     $preview_panel = '<div class="aphront-panel-preview">
     <div id="transaction-preview">
       <div class="aphront-panel-preview-loading-text">
         Loading preview...
       </div>
     </div>
   </div>';
     $transaction_view = new ManiphestTransactionListView();
     $transaction_view->setTransactions($transactions);
     $transaction_view->setHandles($handles);
     $transaction_view->setUser($user);
     $transaction_view->setAuxiliaryFields($aux_fields);
     $transaction_view->setMarkupEngine($engine);
     PhabricatorFeedStoryNotification::updateObjectNotificationViews($user, $task->getPHID());
     return $this->buildStandardPageResponse(array($context_bar, $headsup_panel, $transaction_view, $comment_panel, $preview_panel), array('title' => 'T' . $task->getID() . ' ' . $task->getTitle(), 'pageObjects' => array($task->getPHID())));
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $e_title = null;
     $priority_map = ManiphestTaskPriority::getTaskPriorityMap();
     $task = id(new ManiphestTask())->load($this->id);
     if (!$task) {
         return new Aphront404Response();
     }
     $transactions = id(new ManiphestTransaction())->loadAllWhere('taskID = %d ORDER BY id ASC', $task->getID());
     $phids = array();
     foreach ($transactions as $transaction) {
         foreach ($transaction->extractPHIDs() as $phid) {
             $phids[$phid] = true;
         }
     }
     foreach ($task->getCCPHIDs() as $phid) {
         $phids[$phid] = true;
     }
     foreach ($task->getProjectPHIDs() as $phid) {
         $phids[$phid] = true;
     }
     if ($task->getOwnerPHID()) {
         $phids[$task->getOwnerPHID()] = true;
     }
     $phids[$task->getAuthorPHID()] = true;
     $phids = array_keys($phids);
     $attached = $task->getAttached();
     foreach ($attached as $type => $list) {
         foreach ($list as $phid => $info) {
             $phids[$phid] = true;
         }
     }
     $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
     $engine = PhabricatorMarkupEngine::newManiphestMarkupEngine();
     $dict = array();
     $dict['Status'] = '<strong>' . ManiphestTaskStatus::getTaskStatusFullName($task->getStatus()) . '</strong>';
     $dict['Assigned To'] = $task->getOwnerPHID() ? $handles[$task->getOwnerPHID()]->renderLink() : '<em>None</em>';
     $dict['Priority'] = ManiphestTaskPriority::getTaskPriorityName($task->getPriority());
     $cc = $task->getCCPHIDs();
     if ($cc) {
         $cc_links = array();
         foreach ($cc as $phid) {
             $cc_links[] = $handles[$phid]->renderLink();
         }
         $dict['CC'] = implode(', ', $cc_links);
     } else {
         $dict['CC'] = '<em>None</em>';
     }
     $dict['Author'] = $handles[$task->getAuthorPHID()]->renderLink();
     $projects = $task->getProjectPHIDs();
     if ($projects) {
         $project_links = array();
         foreach ($projects as $phid) {
             $project_links[] = $handles[$phid]->renderLink();
         }
         $dict['Projects'] = implode(', ', $project_links);
     } else {
         $dict['Projects'] = '<em>None</em>';
     }
     if (idx($attached, PhabricatorPHIDConstants::PHID_TYPE_DREV)) {
         $revs = idx($attached, PhabricatorPHIDConstants::PHID_TYPE_DREV);
         $rev_links = array();
         foreach ($revs as $rev => $info) {
             $rev_links[] = $handles[$rev]->renderLink();
         }
         $rev_links = implode('<br />', $rev_links);
         $dict['Revisions'] = $rev_links;
     }
     if (idx($attached, PhabricatorPHIDConstants::PHID_TYPE_FILE)) {
         $file_infos = idx($attached, PhabricatorPHIDConstants::PHID_TYPE_FILE);
         $file_phids = array_keys($file_infos);
         if ($file_phids) {
             $files = id(new PhabricatorFile())->loadAllWhere('phid IN (%Ls)', $file_phids);
             $views = array();
             foreach ($files as $file) {
                 $view = new AphrontFilePreviewView();
                 $view->setFile($file);
                 $views[] = $view->render();
             }
             $dict['Files'] = implode('', $views);
         }
     }
     $dict['Description'] = '<div class="maniphest-task-description">' . '<div class="phabricator-remarkup">' . $engine->markupText($task->getDescription()) . '</div>' . '</div>';
     require_celerity_resource('mainphest-task-detail-css');
     $table = array();
     foreach ($dict as $key => $value) {
         $table[] = '<tr>' . '<th>' . phutil_escape_html($key) . ':</th>' . '<td>' . $value . '</td>' . '</tr>';
     }
     $table = '<table class="maniphest-task-properties">' . implode("\n", $table) . '</table>';
     $actions = array();
     $action = new AphrontHeadsupActionView();
     $action->setName('Edit Task');
     $action->setURI('/maniphest/task/edit/' . $task->getID() . '/');
     $action->setClass('action-edit');
     $actions[] = $action;
     require_celerity_resource('phabricator-object-selector-css');
     require_celerity_resource('javelin-behavior-phabricator-object-selector');
     $action = new AphrontHeadsupActionView();
     $action->setName('Merge Duplicates');
     $action->setURI('/search/attach/' . $task->getPHID() . '/TASK/merge/');
     $action->setWorkflow(true);
     $action->setClass('action-merge');
     $actions[] = $action;
     $action = new AphrontHeadsupActionView();
     $action->setName('Edit Differential Revisions');
     $action->setURI('/search/attach/' . $task->getPHID() . '/DREV/');
     $action->setWorkflow(true);
     $action->setClass('action-attach');
     $actions[] = $action;
     $action_list = new AphrontHeadsupActionListView();
     $action_list->setActions($actions);
     $panel = '<div class="maniphest-panel">' . $action_list->render() . '<div class="maniphest-task-detail-core">' . '<h1>' . '<span class="aphront-headsup-object-name">' . phutil_escape_html('T' . $task->getID()) . '</span>' . ' ' . phutil_escape_html($task->getTitle()) . '</h1>' . $table . '</div>' . '</div>';
     $transaction_types = ManiphestTransactionType::getTransactionTypeMap();
     $resolution_types = ManiphestTaskStatus::getTaskStatusMap();
     if ($task->getStatus() == ManiphestTaskStatus::STATUS_OPEN) {
         $resolution_types = array_select_keys($resolution_types, array(ManiphestTaskStatus::STATUS_CLOSED_RESOLVED, ManiphestTaskStatus::STATUS_CLOSED_WONTFIX, ManiphestTaskStatus::STATUS_CLOSED_INVALID, ManiphestTaskStatus::STATUS_CLOSED_SPITE));
     } else {
         $resolution_types = array(ManiphestTaskStatus::STATUS_OPEN => 'Reopened');
         $transaction_types[ManiphestTransactionType::TYPE_STATUS] = 'Reopen Task';
         unset($transaction_types[ManiphestTransactionType::TYPE_PRIORITY]);
         unset($transaction_types[ManiphestTransactionType::TYPE_OWNER]);
     }
     $default_claim = array($user->getPHID() => $user->getUsername() . ' (' . $user->getRealName() . ')');
     $draft = id(new PhabricatorDraft())->loadOneWhere('authorPHID = %s AND draftKey = %s', $user->getPHID(), $task->getPHID());
     if ($draft) {
         $draft_text = $draft->getDraft();
     } else {
         $draft_text = null;
     }
     $panel_id = celerity_generate_unique_node_id();
     $comment_form = new AphrontFormView();
     $comment_form->setUser($user)->setAction('/maniphest/transaction/save/')->setEncType('multipart/form-data')->addHiddenInput('taskID', $task->getID())->appendChild(id(new AphrontFormSelectControl())->setLabel('Action')->setName('action')->setOptions($transaction_types)->setID('transaction-action'))->appendChild(id(new AphrontFormSelectControl())->setLabel('Resolution')->setName('resolution')->setControlID('resolution')->setControlStyle('display: none')->setOptions($resolution_types))->appendChild(id(new AphrontFormTokenizerControl())->setLabel('Assign To')->setName('assign_to')->setControlID('assign_to')->setControlStyle('display: none')->setID('assign-tokenizer')->setDisableBehavior(true))->appendChild(id(new AphrontFormTokenizerControl())->setLabel('CCs')->setName('ccs')->setControlID('ccs')->setControlStyle('display: none')->setID('cc-tokenizer')->setDisableBehavior(true))->appendChild(id(new AphrontFormSelectControl())->setLabel('Priority')->setName('priority')->setOptions($priority_map)->setControlID('priority')->setControlStyle('display: none')->setValue($task->getPriority()))->appendChild(id(new AphrontFormTokenizerControl())->setLabel('Projects')->setName('projects')->setControlID('projects')->setControlStyle('display: none')->setID('projects-tokenizer')->setDisableBehavior(true))->appendChild(id(new AphrontFormFileControl())->setLabel('File')->setName('file')->setControlID('file')->setControlStyle('display: none'))->appendChild(id(new AphrontFormTextAreaControl())->setLabel('Comments')->setName('comments')->setValue($draft_text)->setID('transaction-comments'))->appendChild(id(new AphrontFormDragAndDropUploadControl())->setLabel('Attached Files')->setName('files')->setDragAndDropTarget($panel_id)->setActivatedClass('aphront-panel-view-drag-and-drop'))->appendChild(id(new AphrontFormSubmitControl())->setValue('Avast!'));
     $control_map = array(ManiphestTransactionType::TYPE_STATUS => 'resolution', ManiphestTransactionType::TYPE_OWNER => 'assign_to', ManiphestTransactionType::TYPE_CCS => 'ccs', ManiphestTransactionType::TYPE_PRIORITY => 'priority', ManiphestTransactionType::TYPE_PROJECTS => 'projects', ManiphestTransactionType::TYPE_ATTACH => 'file');
     Javelin::initBehavior('maniphest-transaction-controls', array('select' => 'transaction-action', 'controlMap' => $control_map, 'tokenizers' => array(ManiphestTransactionType::TYPE_PROJECTS => array('id' => 'projects-tokenizer', 'src' => '/typeahead/common/projects/'), ManiphestTransactionType::TYPE_OWNER => array('id' => 'assign-tokenizer', 'src' => '/typeahead/common/users/', 'value' => $default_claim, 'limit' => 1), ManiphestTransactionType::TYPE_CCS => array('id' => 'cc-tokenizer', 'src' => '/typeahead/common/mailable/'))));
     Javelin::initBehavior('maniphest-transaction-preview', array('uri' => '/maniphest/transaction/preview/' . $task->getID() . '/', 'preview' => 'transaction-preview', 'comments' => 'transaction-comments', 'action' => 'transaction-action', 'map' => $control_map));
     $comment_panel = new AphrontPanelView();
     $comment_panel->appendChild($comment_form);
     $comment_panel->setID($panel_id);
     $comment_panel->addClass('aphront-panel-accent');
     $comment_panel->setHeader('Weigh In');
     $preview_panel = '<div class="aphront-panel-preview">
     <div id="transaction-preview">
       <div class="aphront-panel-preview-loading-text">
         Loading preview...
       </div>
     </div>
   </div>';
     $transaction_view = new ManiphestTransactionListView();
     $transaction_view->setTransactions($transactions);
     $transaction_view->setHandles($handles);
     $transaction_view->setUser($user);
     $transaction_view->setMarkupEngine($engine);
     return $this->buildStandardPageResponse(array($panel, $transaction_view, $comment_panel, $preview_panel), array('title' => 'T' . $task->getID() . ' ' . $task->getTitle()));
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $e_title = null;
     $priority_map = ManiphestTaskPriority::getTaskPriorityMap();
     $task = id(new ManiphestTask())->load($this->id);
     if (!$task) {
         return new Aphront404Response();
     }
     $workflow = $request->getStr('workflow');
     $parent_task = null;
     if ($workflow && is_numeric($workflow)) {
         $parent_task = id(new ManiphestTask())->load($workflow);
     }
     $transactions = id(new ManiphestTransaction())->loadAllWhere('taskID = %d ORDER BY id ASC', $task->getID());
     $phids = array();
     foreach ($transactions as $transaction) {
         foreach ($transaction->extractPHIDs() as $phid) {
             $phids[$phid] = true;
         }
     }
     foreach ($task->getCCPHIDs() as $phid) {
         $phids[$phid] = true;
     }
     foreach ($task->getProjectPHIDs() as $phid) {
         $phids[$phid] = true;
     }
     if ($task->getOwnerPHID()) {
         $phids[$task->getOwnerPHID()] = true;
     }
     $phids[$task->getAuthorPHID()] = true;
     $attached = $task->getAttached();
     foreach ($attached as $type => $list) {
         foreach ($list as $phid => $info) {
             $phids[$phid] = true;
         }
     }
     if ($parent_task) {
         $phids[$parent_task->getPHID()] = true;
     }
     $phids = array_keys($phids);
     $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
     $engine = PhabricatorMarkupEngine::newManiphestMarkupEngine();
     $dict = array();
     $dict['Status'] = '<strong>' . ManiphestTaskStatus::getTaskStatusFullName($task->getStatus()) . '</strong>';
     $dict['Assigned To'] = $task->getOwnerPHID() ? $handles[$task->getOwnerPHID()]->renderLink() : '<em>None</em>';
     $dict['Priority'] = ManiphestTaskPriority::getTaskPriorityName($task->getPriority());
     $cc = $task->getCCPHIDs();
     if ($cc) {
         $cc_links = array();
         foreach ($cc as $phid) {
             $cc_links[] = $handles[$phid]->renderLink();
         }
         $dict['CC'] = implode(', ', $cc_links);
     } else {
         $dict['CC'] = '<em>None</em>';
     }
     $dict['Author'] = $handles[$task->getAuthorPHID()]->renderLink();
     $source = $task->getOriginalEmailSource();
     if ($source) {
         $subject = '[T' . $task->getID() . '] ' . $task->getTitle();
         $dict['From Email'] = phutil_render_tag('a', array('href' => 'mailto:' . $source . '?subject=' . $subject), phutil_escape_html($source));
     }
     $projects = $task->getProjectPHIDs();
     if ($projects) {
         $project_links = array();
         foreach ($projects as $phid) {
             $project_links[] = $handles[$phid]->renderLink();
         }
         $dict['Projects'] = implode(', ', $project_links);
     } else {
         $dict['Projects'] = '<em>None</em>';
     }
     $extensions = ManiphestTaskExtensions::newExtensions();
     $aux_fields = $extensions->getAuxiliaryFieldSpecifications();
     if ($aux_fields) {
         $task->loadAndAttachAuxiliaryAttributes();
         foreach ($aux_fields as $aux_field) {
             $aux_key = $aux_field->getAuxiliaryKey();
             $aux_field->setValue($task->getAuxiliaryAttribute($aux_key));
             $value = $aux_field->renderForDetailView();
             if (strlen($value)) {
                 $dict[$aux_field->getLabel()] = $value;
             }
         }
     }
     $dtasks = idx($attached, PhabricatorPHIDConstants::PHID_TYPE_TASK);
     if ($dtasks) {
         $dtask_links = array();
         foreach ($dtasks as $dtask => $info) {
             $dtask_links[] = $handles[$dtask]->renderLink();
         }
         $dtask_links = implode('<br />', $dtask_links);
         $dict['Depends On'] = $dtask_links;
     }
     $revs = idx($attached, PhabricatorPHIDConstants::PHID_TYPE_DREV);
     if ($revs) {
         $rev_links = array();
         foreach ($revs as $rev => $info) {
             $rev_links[] = $handles[$rev]->renderLink();
         }
         $rev_links = implode('<br />', $rev_links);
         $dict['Revisions'] = $rev_links;
     }
     $file_infos = idx($attached, PhabricatorPHIDConstants::PHID_TYPE_FILE);
     if ($file_infos) {
         $file_phids = array_keys($file_infos);
         $files = id(new PhabricatorFile())->loadAllWhere('phid IN (%Ls)', $file_phids);
         $views = array();
         foreach ($files as $file) {
             $view = new AphrontFilePreviewView();
             $view->setFile($file);
             $views[] = $view->render();
         }
         $dict['Files'] = implode('', $views);
     }
     $dict['Description'] = '<div class="maniphest-task-description">' . '<div class="phabricator-remarkup">' . $engine->markupText($task->getDescription()) . '</div>' . '</div>';
     require_celerity_resource('mainphest-task-detail-css');
     $table = array();
     foreach ($dict as $key => $value) {
         $table[] = '<tr>' . '<th>' . phutil_escape_html($key) . ':</th>' . '<td>' . $value . '</td>' . '</tr>';
     }
     $table = '<table class="maniphest-task-properties">' . implode("\n", $table) . '</table>';
     $context_bar = null;
     if ($parent_task) {
         $context_bar = new AphrontContextBarView();
         $context_bar->addButton(phutil_render_tag('a', array('href' => '/maniphest/task/create/?parent=' . $parent_task->getID(), 'class' => 'green button'), 'Create Another Subtask'));
         $context_bar->appendChild('Created a subtask of <strong>' . $handles[$parent_task->getPHID()]->renderLink() . '</strong>');
     } else {
         if ($workflow == 'create') {
             $context_bar = new AphrontContextBarView();
             $context_bar->addButton(phutil_render_tag('a', array('href' => '/maniphest/task/create/?template=' . $task->getID(), 'class' => 'green button'), 'Create Another Task'));
             $context_bar->appendChild('New task created.');
         }
     }
     $actions = array();
     $action = new AphrontHeadsupActionView();
     $action->setName('Edit Task');
     $action->setURI('/maniphest/task/edit/' . $task->getID() . '/');
     $action->setClass('action-edit');
     $actions[] = $action;
     require_celerity_resource('phabricator-object-selector-css');
     require_celerity_resource('javelin-behavior-phabricator-object-selector');
     $action = new AphrontHeadsupActionView();
     $action->setName('Merge Duplicates');
     $action->setURI('/search/attach/' . $task->getPHID() . '/TASK/merge/');
     $action->setWorkflow(true);
     $action->setClass('action-merge');
     $actions[] = $action;
     $action = new AphrontHeadsupActionView();
     $action->setName('Create Subtask');
     $action->setURI('/maniphest/task/create/?parent=' . $task->getID());
     $action->setClass('action-branch');
     $actions[] = $action;
     $action = new AphrontHeadsupActionView();
     $action->setName('Edit Dependencies');
     $action->setURI('/search/attach/' . $task->getPHID() . '/TASK/dependencies/');
     $action->setWorkflow(true);
     $action->setClass('action-dependencies');
     $actions[] = $action;
     $action = new AphrontHeadsupActionView();
     $action->setName('Edit Differential Revisions');
     $action->setURI('/search/attach/' . $task->getPHID() . '/DREV/');
     $action->setWorkflow(true);
     $action->setClass('action-attach');
     $actions[] = $action;
     $action_list = new AphrontHeadsupActionListView();
     $action_list->setActions($actions);
     $panel = '<div class="maniphest-panel">' . $action_list->render() . '<div class="maniphest-task-detail-core">' . '<h1>' . '<span class="aphront-headsup-object-name">' . phutil_escape_html('T' . $task->getID()) . '</span>' . ' ' . phutil_escape_html($task->getTitle()) . '</h1>' . $table . '</div>' . '</div>';
     $transaction_types = ManiphestTransactionType::getTransactionTypeMap();
     $resolution_types = ManiphestTaskStatus::getTaskStatusMap();
     if ($task->getStatus() == ManiphestTaskStatus::STATUS_OPEN) {
         $resolution_types = array_select_keys($resolution_types, array(ManiphestTaskStatus::STATUS_CLOSED_RESOLVED, ManiphestTaskStatus::STATUS_CLOSED_WONTFIX, ManiphestTaskStatus::STATUS_CLOSED_INVALID, ManiphestTaskStatus::STATUS_CLOSED_SPITE));
     } else {
         $resolution_types = array(ManiphestTaskStatus::STATUS_OPEN => 'Reopened');
         $transaction_types[ManiphestTransactionType::TYPE_STATUS] = 'Reopen Task';
         unset($transaction_types[ManiphestTransactionType::TYPE_PRIORITY]);
         unset($transaction_types[ManiphestTransactionType::TYPE_OWNER]);
     }
     $default_claim = array($user->getPHID() => $user->getUsername() . ' (' . $user->getRealName() . ')');
     $draft = id(new PhabricatorDraft())->loadOneWhere('authorPHID = %s AND draftKey = %s', $user->getPHID(), $task->getPHID());
     if ($draft) {
         $draft_text = $draft->getDraft();
     } else {
         $draft_text = null;
     }
     $panel_id = celerity_generate_unique_node_id();
     $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
     if ($is_serious) {
         // Prevent tasks from being closed "out of spite" in serious business
         // installs.
         unset($resolution_types[ManiphestTaskStatus::STATUS_CLOSED_SPITE]);
     }
     $remarkup_href = PhabricatorEnv::getDoclink('article/Remarkup_Reference.html');
     $comment_form = new AphrontFormView();
     $comment_form->setUser($user)->setAction('/maniphest/transaction/save/')->setEncType('multipart/form-data')->addHiddenInput('taskID', $task->getID())->appendChild(id(new AphrontFormSelectControl())->setLabel('Action')->setName('action')->setOptions($transaction_types)->setID('transaction-action'))->appendChild(id(new AphrontFormSelectControl())->setLabel('Resolution')->setName('resolution')->setControlID('resolution')->setControlStyle('display: none')->setOptions($resolution_types))->appendChild(id(new AphrontFormTokenizerControl())->setLabel('Assign To')->setName('assign_to')->setControlID('assign_to')->setControlStyle('display: none')->setID('assign-tokenizer')->setDisableBehavior(true))->appendChild(id(new AphrontFormTokenizerControl())->setLabel('CCs')->setName('ccs')->setControlID('ccs')->setControlStyle('display: none')->setID('cc-tokenizer')->setDisableBehavior(true))->appendChild(id(new AphrontFormSelectControl())->setLabel('Priority')->setName('priority')->setOptions($priority_map)->setControlID('priority')->setControlStyle('display: none')->setValue($task->getPriority()))->appendChild(id(new AphrontFormTokenizerControl())->setLabel('Projects')->setName('projects')->setControlID('projects')->setControlStyle('display: none')->setID('projects-tokenizer')->setDisableBehavior(true))->appendChild(id(new AphrontFormFileControl())->setLabel('File')->setName('file')->setControlID('file')->setControlStyle('display: none'))->appendChild(id(new AphrontFormTextAreaControl())->setLabel('Comments')->setName('comments')->setValue($draft_text)->setCaption(phutil_render_tag('a', array('href' => $remarkup_href, 'tabindex' => '-1', 'target' => '_blank'), 'Formatting Reference'))->setID('transaction-comments'))->appendChild(id(new AphrontFormDragAndDropUploadControl())->setLabel('Attached Files')->setName('files')->setDragAndDropTarget($panel_id)->setActivatedClass('aphront-panel-view-drag-and-drop'))->appendChild(id(new AphrontFormSubmitControl())->setValue($is_serious ? 'Submit' : 'Avast!'));
     $control_map = array(ManiphestTransactionType::TYPE_STATUS => 'resolution', ManiphestTransactionType::TYPE_OWNER => 'assign_to', ManiphestTransactionType::TYPE_CCS => 'ccs', ManiphestTransactionType::TYPE_PRIORITY => 'priority', ManiphestTransactionType::TYPE_PROJECTS => 'projects', ManiphestTransactionType::TYPE_ATTACH => 'file');
     Javelin::initBehavior('maniphest-transaction-controls', array('select' => 'transaction-action', 'controlMap' => $control_map, 'tokenizers' => array(ManiphestTransactionType::TYPE_PROJECTS => array('id' => 'projects-tokenizer', 'src' => '/typeahead/common/projects/', 'ondemand' => PhabricatorEnv::getEnvConfig('tokenizer.ondemand')), ManiphestTransactionType::TYPE_OWNER => array('id' => 'assign-tokenizer', 'src' => '/typeahead/common/users/', 'value' => $default_claim, 'limit' => 1, 'ondemand' => PhabricatorEnv::getEnvConfig('tokenizer.ondemand')), ManiphestTransactionType::TYPE_CCS => array('id' => 'cc-tokenizer', 'src' => '/typeahead/common/mailable/', 'ondemand' => PhabricatorEnv::getEnvConfig('tokenizer.ondemand')))));
     Javelin::initBehavior('maniphest-transaction-preview', array('uri' => '/maniphest/transaction/preview/' . $task->getID() . '/', 'preview' => 'transaction-preview', 'comments' => 'transaction-comments', 'action' => 'transaction-action', 'map' => $control_map));
     $comment_panel = new AphrontPanelView();
     $comment_panel->appendChild($comment_form);
     $comment_panel->setID($panel_id);
     $comment_panel->addClass('aphront-panel-accent');
     $comment_panel->setHeader($is_serious ? 'Add Comment' : 'Weigh In');
     $preview_panel = '<div class="aphront-panel-preview">
     <div id="transaction-preview">
       <div class="aphront-panel-preview-loading-text">
         Loading preview...
       </div>
     </div>
   </div>';
     $transaction_view = new ManiphestTransactionListView();
     $transaction_view->setTransactions($transactions);
     $transaction_view->setHandles($handles);
     $transaction_view->setUser($user);
     $transaction_view->setMarkupEngine($engine);
     return $this->buildStandardPageResponse(array($context_bar, $panel, $transaction_view, $comment_panel, $preview_panel), array('title' => 'T' . $task->getID() . ' ' . $task->getTitle()));
 }