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'); } $tasks = id(new ManiphestTaskQuery())->setViewer($viewer)->withIDs($task_ids)->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->needSubscriberPHIDs(true)->needProjectPHIDs(true)->execute(); if ($project) { $cancel_uri = '/project/sprint/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() && 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($viewer)->setContentSourceFromRequest($request)->setContinueOnNoEffect(true)->setContinueOnMissingFields(true)->applyTransactions($task, $xactions); } } return id(new AphrontRedirectResponse())->setURI($redirect_uri); } $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); 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())), '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)); }
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); $crumbs->setBorder(true); $header = id(new PHUIHeaderView())->setHeader(pht('Batch Editor'))->setHeaderIcon('fa-pencil-square-o'); $task_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Selected Tasks'))->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)->setObjectList($list); $form_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Actions'))->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)->setForm($form); $view = id(new PHUITwoColumnView())->setHeader($header)->setFooter(array($task_box, $form_box)); return $this->newPage()->setTitle($title)->setCrumbs($crumbs)->appendChild($view); }