public function processRequest()
 {
     $this->requireApplicationCapability(ManiphestBulkEditCapability::CAPABILITY);
     $request = $this->getRequest();
     $user = $request->getUser();
     $task_ids = $request->getArr('batch');
     $tasks = id(new ManiphestTaskQuery())->setViewer($user)->withIDs($task_ids)->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->execute();
     $actions = $request->getStr('actions');
     if ($actions) {
         $actions = json_decode($actions, true);
     }
     if ($request->isFormPost() && is_array($actions)) {
         foreach ($tasks as $task) {
             $field_list = PhabricatorCustomField::getObjectFields($task, PhabricatorCustomField::ROLE_EDIT);
             $field_list->readFieldsFromStorage($task);
             $xactions = $this->buildTransactions($actions, $task);
             if ($xactions) {
                 // TODO: Set content source to "batch edit".
                 $editor = id(new ManiphestTransactionEditor())->setActor($user)->setContentSourceFromRequest($request)->setContinueOnNoEffect(true)->setContinueOnMissingFields(true)->applyTransactions($task, $xactions);
             }
         }
         $task_ids = implode(',', mpull($tasks, 'getID'));
         return id(new AphrontRedirectResponse())->setURI('/maniphest/?ids=' . $task_ids);
     }
     $handles = ManiphestTaskListView::loadTaskHandles($user, $tasks);
     $list = new ManiphestTaskListView();
     $list->setTasks($tasks);
     $list->setUser($user);
     $list->setHandles($handles);
     $template = new AphrontTokenizerTemplateView();
     $template = $template->render();
     $projects_source = new PhabricatorProjectDatasource();
     $mailable_source = new PhabricatorMetaMTAMailableDatasource();
     $owner_source = new PhabricatorTypeaheadOwnerDatasource();
     require_celerity_resource('maniphest-batch-editor');
     Javelin::initBehavior('maniphest-batch-editor', array('root' => 'maniphest-batch-edit-form', 'tokenizerTemplate' => $template, 'sources' => array('project' => array('src' => $projects_source->getDatasourceURI(), 'placeholder' => $projects_source->getPlaceholderText()), 'owner' => array('src' => $owner_source->getDatasourceURI(), 'placeholder' => $owner_source->getPlaceholderText(), 'limit' => 1), 'cc' => array('src' => $mailable_source->getDatasourceURI(), 'placeholder' => $mailable_source->getPlaceholderText())), 'input' => 'batch-form-actions', 'priorityMap' => ManiphestTaskPriority::getTaskPriorityMap(), 'statusMap' => ManiphestTaskStatus::getTaskStatusMap()));
     $form = new AphrontFormView();
     $form->setUser($user);
     $form->setID('maniphest-batch-edit-form');
     foreach ($tasks as $task) {
         $form->appendChild(phutil_tag('input', array('type' => 'hidden', 'name' => 'batch[]', 'value' => $task->getID())));
     }
     $form->appendChild(phutil_tag('input', array('type' => 'hidden', 'name' => 'actions', 'id' => 'batch-form-actions')));
     $form->appendChild(phutil_tag('p', array(), pht('These tasks will be edited:')));
     $form->appendChild($list);
     $form->appendChild(id(new AphrontFormInsetView())->setTitle('Actions')->setRightButton(javelin_tag('a', array('href' => '#', 'class' => 'button green', 'sigil' => 'add-action', 'mustcapture' => true), pht('Add Another Action')))->setContent(javelin_tag('table', array('sigil' => 'maniphest-batch-actions', 'class' => 'maniphest-batch-actions-table'), '')))->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Update Tasks'))->addCancelButton('/maniphest/'));
     $title = pht('Batch Editor');
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb($title);
     $form_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Batch Edit Tasks'))->setForm($form);
     return $this->buildApplicationPage(array($crumbs, $form_box), array('title' => $title, 'device' => false));
 }
 public function getValueControlTemplate()
 {
     $projects_source = new PhabricatorProjectDatasource();
     return array('markup' => new AphrontTokenizerTemplateView(), 'uri' => $projects_source->getDatasourceURI(), 'placeholder' => $projects_source->getPlaceholderText());
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $this->getViewer();
     $this->requireApplicationCapability(ManiphestBulkEditCapability::CAPABILITY);
     $project = null;
     $board_id = $request->getInt('board');
     if ($board_id) {
         $project = id(new PhabricatorProjectQuery())->setViewer($viewer)->withIDs(array($board_id))->executeOne();
         if (!$project) {
             return new Aphront404Response();
         }
     }
     $task_ids = $request->getArr('batch');
     if (!$task_ids) {
         $task_ids = $request->getStrList('batch');
     }
     if (!$task_ids) {
         throw new Exception(pht('No tasks are selected.'));
     }
     $tasks = id(new ManiphestTaskQuery())->setViewer($viewer)->withIDs($task_ids)->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->needSubscriberPHIDs(true)->needProjectPHIDs(true)->execute();
     if (!$tasks) {
         throw new Exception(pht("You don't have permission to edit any of the selected tasks."));
     }
     if ($project) {
         $cancel_uri = '/project/board/' . $project->getID() . '/';
         $redirect_uri = $cancel_uri;
     } else {
         $cancel_uri = '/maniphest/';
         $redirect_uri = '/maniphest/?ids=' . implode(',', mpull($tasks, 'getID'));
     }
     $actions = $request->getStr('actions');
     if ($actions) {
         $actions = phutil_json_decode($actions);
     }
     if ($request->isFormPost() && $actions) {
         $job = PhabricatorWorkerBulkJob::initializeNewJob($viewer, new ManiphestTaskEditBulkJobType(), array('taskPHIDs' => mpull($tasks, 'getPHID'), 'actions' => $actions, 'cancelURI' => $cancel_uri, 'doneURI' => $redirect_uri));
         $type_status = PhabricatorWorkerBulkJobTransaction::TYPE_STATUS;
         $xactions = array();
         $xactions[] = id(new PhabricatorWorkerBulkJobTransaction())->setTransactionType($type_status)->setNewValue(PhabricatorWorkerBulkJob::STATUS_CONFIRM);
         $editor = id(new PhabricatorWorkerBulkJobEditor())->setActor($viewer)->setContentSourceFromRequest($request)->setContinueOnMissingFields(true)->applyTransactions($job, $xactions);
         return id(new AphrontRedirectResponse())->setURI($job->getMonitorURI());
     }
     $handles = ManiphestTaskListView::loadTaskHandles($viewer, $tasks);
     $list = new ManiphestTaskListView();
     $list->setTasks($tasks);
     $list->setUser($viewer);
     $list->setHandles($handles);
     $template = new AphrontTokenizerTemplateView();
     $template = $template->render();
     $projects_source = new PhabricatorProjectDatasource();
     $mailable_source = new PhabricatorMetaMTAMailableDatasource();
     $mailable_source->setViewer($viewer);
     $owner_source = new ManiphestAssigneeDatasource();
     $owner_source->setViewer($viewer);
     $spaces_source = id(new PhabricatorSpacesNamespaceDatasource())->setViewer($viewer);
     require_celerity_resource('maniphest-batch-editor');
     Javelin::initBehavior('maniphest-batch-editor', array('root' => 'maniphest-batch-edit-form', 'tokenizerTemplate' => $template, 'sources' => array('project' => array('src' => $projects_source->getDatasourceURI(), 'placeholder' => $projects_source->getPlaceholderText(), 'browseURI' => $projects_source->getBrowseURI()), 'owner' => array('src' => $owner_source->getDatasourceURI(), 'placeholder' => $owner_source->getPlaceholderText(), 'browseURI' => $owner_source->getBrowseURI(), 'limit' => 1), 'cc' => array('src' => $mailable_source->getDatasourceURI(), 'placeholder' => $mailable_source->getPlaceholderText(), 'browseURI' => $mailable_source->getBrowseURI()), 'spaces' => array('src' => $spaces_source->getDatasourceURI(), 'placeholder' => $spaces_source->getPlaceholderText(), 'browseURI' => $spaces_source->getBrowseURI(), 'limit' => 1)), 'input' => 'batch-form-actions', 'priorityMap' => ManiphestTaskPriority::getTaskPriorityMap(), 'statusMap' => ManiphestTaskStatus::getTaskStatusMap()));
     $form = id(new AphrontFormView())->setUser($viewer)->addHiddenInput('board', $board_id)->setID('maniphest-batch-edit-form');
     foreach ($tasks as $task) {
         $form->appendChild(phutil_tag('input', array('type' => 'hidden', 'name' => 'batch[]', 'value' => $task->getID())));
     }
     $form->appendChild(phutil_tag('input', array('type' => 'hidden', 'name' => 'actions', 'id' => 'batch-form-actions')));
     $form->appendChild(id(new PHUIFormInsetView())->setTitle(pht('Actions'))->setRightButton(javelin_tag('a', array('href' => '#', 'class' => 'button green', 'sigil' => 'add-action', 'mustcapture' => true), pht('Add Another Action')))->setContent(javelin_tag('table', array('sigil' => 'maniphest-batch-actions', 'class' => 'maniphest-batch-actions-table'), '')))->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Update Tasks'))->addCancelButton($cancel_uri));
     $title = pht('Batch Editor');
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb($title);
     $task_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Selected Tasks'))->setObjectList($list);
     $form_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Batch Editor'))->setForm($form);
     return $this->buildApplicationPage(array($crumbs, $task_box, $form_box), array('title' => $title));
 }
 protected function renderInput()
 {
     $id = $this->getID();
     if (!$id) {
         $id = celerity_generate_unique_node_id();
         $this->setID($id);
     }
     $viewer = $this->getUser();
     if (!$viewer) {
         throw new PhutilInvalidStateException('setUser');
     }
     // We need to have this if previews render images, since Ajax can not
     // currently ship JS or CSS.
     require_celerity_resource('lightbox-attachment-css');
     if (!$this->getDisabled()) {
         Javelin::initBehavior('aphront-drag-and-drop-textarea', array('target' => $id, 'activatedClass' => 'aphront-textarea-drag-and-drop', 'uri' => '/file/dropupload/', 'chunkThreshold' => PhabricatorFileStorageEngine::getChunkThreshold()));
     }
     $root_id = celerity_generate_unique_node_id();
     $user_datasource = new PhabricatorPeopleDatasource();
     $proj_datasource = new PhabricatorProjectDatasource();
     Javelin::initBehavior('phabricator-remarkup-assist', array('pht' => array('bold text' => pht('bold text'), 'italic text' => pht('italic text'), 'monospaced text' => pht('monospaced text'), 'List Item' => pht('List Item'), 'Quoted Text' => pht('Quoted Text'), 'data' => pht('data'), 'name' => pht('name'), 'URL' => pht('URL')), 'disabled' => $this->getDisabled(), 'rootID' => $root_id, 'autocompleteMap' => (object) array(64 => array('datasourceURI' => $user_datasource->getDatasourceURI(), 'headerIcon' => 'fa-user', 'headerText' => pht('Find User:'******'hintText' => $user_datasource->getPlaceholderText()), 35 => array('datasourceURI' => $proj_datasource->getDatasourceURI(), 'headerIcon' => 'fa-briefcase', 'headerText' => pht('Find Project:'), 'hintText' => $proj_datasource->getPlaceholderText()))));
     Javelin::initBehavior('phabricator-tooltips', array());
     $actions = array('fa-bold' => array('tip' => pht('Bold'), 'nodevice' => true), 'fa-italic' => array('tip' => pht('Italics'), 'nodevice' => true), 'fa-text-width' => array('tip' => pht('Monospaced'), 'nodevice' => true), 'fa-link' => array('tip' => pht('Link'), 'nodevice' => true), array('spacer' => true, 'nodevice' => true), 'fa-list-ul' => array('tip' => pht('Bulleted List'), 'nodevice' => true), 'fa-list-ol' => array('tip' => pht('Numbered List'), 'nodevice' => true), 'fa-code' => array('tip' => pht('Code Block'), 'nodevice' => true), 'fa-quote-right' => array('tip' => pht('Quote'), 'nodevice' => true), 'fa-table' => array('tip' => pht('Table'), 'nodevice' => true), 'fa-cloud-upload' => array('tip' => pht('Upload File')));
     $can_use_macros = !$this->disableMacro && function_exists('imagettftext');
     if ($can_use_macros) {
         $can_use_macros = PhabricatorApplication::isClassInstalledForViewer('PhabricatorMacroApplication', $viewer);
     }
     if ($can_use_macros) {
         $actions[] = array('spacer' => true);
         $actions['fa-meh-o'] = array('tip' => pht('Meme'));
     }
     $actions['fa-eye'] = array('tip' => pht('Preview'), 'align' => 'right');
     $actions[] = array('spacer' => true, 'align' => 'right');
     $actions['fa-life-bouy'] = array('tip' => pht('Help'), 'align' => 'right', 'href' => PhabricatorEnv::getDoclink('Remarkup Reference'));
     if (!$this->disableFullScreen) {
         $actions[] = array('spacer' => true, 'align' => 'right');
         $actions['fa-arrows-alt'] = array('tip' => pht('Fullscreen Mode'), 'align' => 'right');
     }
     $buttons = array();
     foreach ($actions as $action => $spec) {
         $classes = array();
         if (idx($spec, 'align') == 'right') {
             $classes[] = 'remarkup-assist-right';
         }
         if (idx($spec, 'nodevice')) {
             $classes[] = 'remarkup-assist-nodevice';
         }
         if (idx($spec, 'spacer')) {
             $classes[] = 'remarkup-assist-separator';
             $buttons[] = phutil_tag('span', array('class' => implode(' ', $classes)), '');
             continue;
         } else {
             $classes[] = 'remarkup-assist-button';
         }
         $href = idx($spec, 'href', '#');
         if ($href == '#') {
             $meta = array('action' => $action);
             $mustcapture = true;
             $target = null;
         } else {
             $meta = array();
             $mustcapture = null;
             $target = '_blank';
         }
         $content = null;
         $tip = idx($spec, 'tip');
         if ($tip) {
             $meta['tip'] = $tip;
             $content = javelin_tag('span', array('aural' => true), $tip);
         }
         $sigils = array();
         $sigils[] = 'remarkup-assist';
         if (!$this->getDisabled()) {
             $sigils[] = 'has-tooltip';
         }
         $buttons[] = javelin_tag('a', array('class' => implode(' ', $classes), 'href' => $href, 'sigil' => implode(' ', $sigils), 'meta' => $meta, 'mustcapture' => $mustcapture, 'target' => $target, 'tabindex' => -1), phutil_tag('div', array('class' => 'remarkup-assist phui-icon-view phui-font-fa bluegrey ' . $action), $content));
     }
     $buttons = phutil_tag('div', array('class' => 'remarkup-assist-bar'), $buttons);
     $monospaced_textareas = null;
     $monospaced_textareas_class = null;
     $monospaced_textareas = $viewer->loadPreferences()->getPreference(PhabricatorUserPreferences::PREFERENCE_MONOSPACED_TEXTAREAS);
     if ($monospaced_textareas == 'enabled') {
         $monospaced_textareas_class = 'PhabricatorMonospaced';
     }
     $this->setCustomClass('remarkup-assist-textarea ' . $monospaced_textareas_class);
     return javelin_tag('div', array('sigil' => 'remarkup-assist-control', 'class' => $this->getDisabled() ? 'disabled-control' : null, 'id' => $root_id), array($buttons, parent::renderInput()));
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $e_title = null;
     $priority_map = ManiphestTaskPriority::getTaskPriorityMap();
     $task = id(new ManiphestTaskQuery())->setViewer($user)->withIDs(array($this->id))->executeOne();
     if (!$task) {
         return new Aphront404Response();
     }
     $workflow = $request->getStr('workflow');
     $parent_task = null;
     if ($workflow && is_numeric($workflow)) {
         $parent_task = id(new ManiphestTaskQuery())->setViewer($user)->withIDs(array($workflow))->executeOne();
     }
     $transactions = id(new ManiphestTransactionQuery())->setViewer($user)->withObjectPHIDs(array($task->getPHID()))->needComments(true)->execute();
     $field_list = PhabricatorCustomField::getObjectFields($task, PhabricatorCustomField::ROLE_VIEW);
     $field_list->setViewer($user)->readFieldsFromStorage($task);
     $e_commit = ManiphestTaskHasCommitEdgeType::EDGECONST;
     $e_dep_on = PhabricatorEdgeConfig::TYPE_TASK_DEPENDS_ON_TASK;
     $e_dep_by = PhabricatorEdgeConfig::TYPE_TASK_DEPENDED_ON_BY_TASK;
     $e_rev = ManiphestTaskHasRevisionEdgeType::EDGECONST;
     $e_mock = PhabricatorEdgeConfig::TYPE_TASK_HAS_MOCK;
     $phid = $task->getPHID();
     $query = id(new PhabricatorEdgeQuery())->withSourcePHIDs(array($phid))->withEdgeTypes(array($e_commit, $e_dep_on, $e_dep_by, $e_rev, $e_mock));
     $edges = idx($query->execute(), $phid);
     $phids = array_fill_keys($query->getDestinationPHIDs(), 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);
     $this->loadHandles($phids);
     $handles = $this->getLoadedHandles();
     $context_bar = null;
     if ($parent_task) {
         $context_bar = new AphrontContextBarView();
         $context_bar->addButton(phutil_tag('a', array('href' => '/maniphest/task/create/?parent=' . $parent_task->getID(), 'class' => 'green button'), pht('Create Another Subtask')));
         $context_bar->appendChild(hsprintf('Created a subtask of <strong>%s</strong>', $this->getHandle($parent_task->getPHID())->renderLink()));
     } else {
         if ($workflow == 'create') {
             $context_bar = new AphrontContextBarView();
             $context_bar->addButton(phutil_tag('label', array(), 'Create Another'));
             $context_bar->addButton(phutil_tag('a', array('href' => '/maniphest/task/create/?template=' . $task->getID(), 'class' => 'green button'), pht('Similar Task')));
             $context_bar->addButton(phutil_tag('a', array('href' => '/maniphest/task/create/', 'class' => 'green button'), pht('Empty Task')));
             $context_bar->appendChild(pht('New task created.'));
         }
     }
     $engine = new PhabricatorMarkupEngine();
     $engine->setViewer($user);
     $engine->addObject($task, ManiphestTask::MARKUP_FIELD_DESCRIPTION);
     foreach ($transactions as $modern_xaction) {
         if ($modern_xaction->getComment()) {
             $engine->addObject($modern_xaction->getComment(), PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT);
         }
     }
     $engine->process();
     $resolution_types = ManiphestTaskStatus::getTaskStatusMap();
     $transaction_types = array(PhabricatorTransactions::TYPE_COMMENT => pht('Comment'), ManiphestTransaction::TYPE_STATUS => pht('Change Status'), ManiphestTransaction::TYPE_OWNER => pht('Reassign / Claim'), ManiphestTransaction::TYPE_CCS => pht('Add CCs'), ManiphestTransaction::TYPE_PRIORITY => pht('Change Priority'), ManiphestTransaction::TYPE_PROJECTS => pht('Associate Projects'));
     // Remove actions the user doesn't have permission to take.
     $requires = array(ManiphestTransaction::TYPE_OWNER => ManiphestEditAssignCapability::CAPABILITY, ManiphestTransaction::TYPE_PRIORITY => ManiphestEditPriorityCapability::CAPABILITY, ManiphestTransaction::TYPE_PROJECTS => ManiphestEditProjectsCapability::CAPABILITY, ManiphestTransaction::TYPE_STATUS => ManiphestEditStatusCapability::CAPABILITY);
     foreach ($transaction_types as $type => $name) {
         if (isset($requires[$type])) {
             if (!$this->hasApplicationCapability($requires[$type])) {
                 unset($transaction_types[$type]);
             }
         }
     }
     // Don't show an option to change to the current status, or to change to
     // the duplicate status explicitly.
     unset($resolution_types[$task->getStatus()]);
     unset($resolution_types[ManiphestTaskStatus::getDuplicateStatus()]);
     // Don't show owner/priority changes for closed tasks, as they don't make
     // much sense.
     if ($task->isClosed()) {
         unset($transaction_types[ManiphestTransaction::TYPE_PRIORITY]);
         unset($transaction_types[ManiphestTransaction::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;
     }
     $comment_form = new AphrontFormView();
     $comment_form->setUser($user)->setWorkflow(true)->setAction('/maniphest/transaction/save/')->setEncType('multipart/form-data')->addHiddenInput('taskID', $task->getID())->appendChild(id(new AphrontFormSelectControl())->setLabel(pht('Action'))->setName('action')->setOptions($transaction_types)->setID('transaction-action'))->appendChild(id(new AphrontFormSelectControl())->setLabel(pht('Status'))->setName('resolution')->setControlID('resolution')->setControlStyle('display: none')->setOptions($resolution_types))->appendChild(id(new AphrontFormTokenizerControl())->setLabel(pht('Assign To'))->setName('assign_to')->setControlID('assign_to')->setControlStyle('display: none')->setID('assign-tokenizer')->setDisableBehavior(true))->appendChild(id(new AphrontFormTokenizerControl())->setLabel(pht('CCs'))->setName('ccs')->setControlID('ccs')->setControlStyle('display: none')->setID('cc-tokenizer')->setDisableBehavior(true))->appendChild(id(new AphrontFormSelectControl())->setLabel(pht('Priority'))->setName('priority')->setOptions($priority_map)->setControlID('priority')->setControlStyle('display: none')->setValue($task->getPriority()))->appendChild(id(new AphrontFormTokenizerControl())->setLabel(pht('Projects'))->setName('projects')->setControlID('projects')->setControlStyle('display: none')->setID('projects-tokenizer')->setDisableBehavior(true))->appendChild(id(new AphrontFormFileControl())->setLabel(pht('File'))->setName('file')->setControlID('file')->setControlStyle('display: none'))->appendChild(id(new PhabricatorRemarkupControl())->setLabel(pht('Comments'))->setName('comments')->setValue($draft_text)->setID('transaction-comments')->setUser($user))->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Submit')));
     $control_map = array(ManiphestTransaction::TYPE_STATUS => 'resolution', ManiphestTransaction::TYPE_OWNER => 'assign_to', ManiphestTransaction::TYPE_CCS => 'ccs', ManiphestTransaction::TYPE_PRIORITY => 'priority', ManiphestTransaction::TYPE_PROJECTS => 'projects');
     $projects_source = new PhabricatorProjectDatasource();
     $users_source = new PhabricatorPeopleDatasource();
     $mailable_source = new PhabricatorMetaMTAMailableDatasource();
     $tokenizer_map = array(ManiphestTransaction::TYPE_PROJECTS => array('id' => 'projects-tokenizer', 'src' => $projects_source->getDatasourceURI(), 'placeholder' => $projects_source->getPlaceholderText()), ManiphestTransaction::TYPE_OWNER => array('id' => 'assign-tokenizer', 'src' => $users_source->getDatasourceURI(), 'value' => $default_claim, 'limit' => 1, 'placeholder' => $users_source->getPlaceholderText()), ManiphestTransaction::TYPE_CCS => array('id' => 'cc-tokenizer', 'src' => $mailable_source->getDatasourceURI(), 'placeholder' => $mailable_source->getPlaceholderText()));
     // TODO: Initializing these behaviors for logged out users fatals things.
     if ($user->isLoggedIn()) {
         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));
     }
     $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
     $comment_header = $is_serious ? pht('Add Comment') : pht('Weigh In');
     $preview_panel = phutil_tag_div('aphront-panel-preview', phutil_tag('div', array('id' => 'transaction-preview'), phutil_tag_div('aphront-panel-preview-loading-text', pht('Loading preview...'))));
     $timeline = id(new PhabricatorApplicationTransactionView())->setUser($user)->setObjectPHID($task->getPHID())->setTransactions($transactions)->setMarkupEngine($engine);
     $object_name = 'T' . $task->getID();
     $actions = $this->buildActionView($task);
     $crumbs = $this->buildApplicationCrumbs()->addTextCrumb($object_name, '/' . $object_name)->setActionList($actions);
     $header = $this->buildHeaderView($task);
     $properties = $this->buildPropertyView($task, $field_list, $edges, $actions);
     $description = $this->buildDescriptionView($task, $engine);
     if (!$user->isLoggedIn()) {
         // TODO: Eventually, everything should run through this. For now, we're
         // only using it to get a consistent "Login to Comment" button.
         $comment_box = id(new PhabricatorApplicationTransactionCommentView())->setUser($user)->setRequestURI($request->getRequestURI());
         $preview_panel = null;
     } else {
         $comment_box = id(new PHUIObjectBoxView())->setFlush(true)->setHeaderText($comment_header)->appendChild($comment_form);
         $timeline->setQuoteTargetID('transaction-comments');
         $timeline->setQuoteRef($object_name);
     }
     $object_box = id(new PHUIObjectBoxView())->setHeader($header)->addPropertyList($properties);
     if ($description) {
         $object_box->addPropertyList($description);
     }
     return $this->buildApplicationPage(array($crumbs, $context_bar, $object_box, $timeline, $comment_box, $preview_panel), array('title' => 'T' . $task->getID() . ' ' . $task->getTitle(), 'pageObjects' => array($task->getPHID())));
 }