public function getItem()
 {
     $task = $this->getTask();
     $owner = $this->getOwner();
     $can_edit = $this->getCanEdit();
     $viewer = $this->getViewer();
     $color_map = ManiphestTaskPriority::getColorMap();
     $bar_color = idx($color_map, $task->getPriority(), 'grey');
     $card = id(new PHUIObjectItemView())->setObject($task)->setUser($viewer)->setObjectName('T' . $task->getID())->setHeader($task->getTitle())->setGrippable($can_edit)->setHref('/T' . $task->getID())->addSigil('project-card')->setDisabled($task->isClosed())->setMetadata(array('objectPHID' => $task->getPHID()))->addAction(id(new PHUIListItemView())->setName(pht('Edit'))->setIcon('fa-pencil')->addSigil('edit-project-card')->setHref('/maniphest/task/edit/' . $task->getID() . '/'))->setBarColor($bar_color);
     if ($owner) {
         $card->addHandleIcon($owner, $owner->getName());
     }
     $cover_file = $this->getCoverImageFile();
     if ($cover_file) {
         $card->setCoverImage($cover_file->getBestURI());
     }
     if ($task->isClosed()) {
         $icon = ManiphestTaskStatus::getStatusIcon($task->getStatus());
         $icon = id(new PHUIIconView())->setIcon($icon . ' grey');
         $card->addAttribute($icon);
         $card->setBarColor('grey');
     }
     $project_handles = $this->getProjectHandles();
     if ($project_handles) {
         $tag_list = id(new PHUIHandleTagListView())->setSlim(true)->setHandles($project_handles);
         $card->addAttribute($tag_list);
     }
     return $card;
 }
Exemple #2
0
 public static function initializeNewTask(PhabricatorUser $actor)
 {
     $app = id(new PhabricatorApplicationQuery())->setViewer($actor)->withClasses(array('PhabricatorManiphestApplication'))->executeOne();
     $view_policy = $app->getPolicy(ManiphestDefaultViewCapability::CAPABILITY);
     $edit_policy = $app->getPolicy(ManiphestDefaultEditCapability::CAPABILITY);
     return id(new ManiphestTask())->setStatus(ManiphestTaskStatus::getDefaultStatus())->setPriority(ManiphestTaskPriority::getDefaultPriority())->setAuthorPHID($actor->getPHID())->setViewPolicy($view_policy)->setEditPolicy($edit_policy)->setSpacePHID($actor->getDefaultSpacePHID())->attachProjectPHIDs(array())->attachSubscriberPHIDs(array());
 }
 protected function renderActionEffectDescription($type, $data)
 {
     switch ($type) {
         case self::DO_PRIORITY:
             return pht('Changed task priority to "%s".', ManiphestTaskPriority::getTaskPriorityName($data));
     }
 }
 protected function newTableRow($phid, $object, $trace)
 {
     $viewer = $this->getViewer();
     if ($object) {
         $status = $object->getStatus();
         $priority = $object->getPriority();
         $status_icon = ManiphestTaskStatus::getStatusIcon($status);
         $status_name = ManiphestTaskStatus::getTaskStatusName($status);
         $priority_color = ManiphestTaskPriority::getTaskPriorityColor($priority);
         if ($object->isClosed()) {
             $priority_color = 'grey';
         }
         $status = array(id(new PHUIIconView())->setIcon($status_icon, $priority_color), ' ', $status_name);
         $owner_phid = $object->getOwnerPHID();
         if ($owner_phid) {
             $assigned = $viewer->renderHandle($owner_phid);
         } else {
             $assigned = phutil_tag('em', array(), pht('None'));
         }
         $link = phutil_tag('a', array('href' => $object->getURI()), $object->getTitle());
         $link = array($object->getMonogram(), ' ', $link);
     } else {
         $status = null;
         $assigned = null;
         $link = $viewer->renderHandle($phid);
     }
     return array($trace, $status, $assigned, $link);
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $task = new ManiphestTask();
     $task->setPriority(ManiphestTaskPriority::getDefaultPriority());
     $task->setAuthorPHID($request->getUser()->getPHID());
     $this->applyRequest($task, $request, $is_new = true);
     return $this->buildTaskInfoDictionary($task);
 }
 private function buildResults()
 {
     $results = array();
     $priority_map = ManiphestTaskPriority::getTaskPriorityMap();
     foreach ($priority_map as $value => $name) {
         $results[$value] = id(new PhabricatorTypeaheadResult())->setIcon(ManiphestTaskPriority::getTaskPriorityIcon($value))->setPHID($value)->setName($name);
     }
     return $results;
 }
 public function getEditorValue(PhabricatorUser $viewer, $value)
 {
     $priority_map = ManiphestTaskPriority::getTaskPriorityMap();
     $value_map = array();
     foreach ($value as $priority) {
         $value_map[$priority] = idx($priority_map, $priority, $priority);
     }
     return $value_map;
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $task_id = $request->getValue('task_id');
     $task = id(new ManiphestTask())->load($task_id);
     if (!$task) {
         throw new ConduitException('ERR_BAD_TASK');
     }
     $result = array('id' => $task->getID(), 'phid' => $task->getPHID(), 'authorPHID' => $task->getAuthorPHID(), 'ownerPHID' => $task->getAuthorPHID(), 'ccPHIDs' => $task->getCCPHIDs(), 'status' => $task->getStatus(), 'priority' => ManiphestTaskPriority::getTaskPriorityName($task->getPriority()), 'title' => $task->getTitle(), 'description' => $task->getDescription(), 'projectPHIDs' => $task->getProjectPHIDs(), 'uri' => PhabricatorEnv::getProductionURI('/T' . $task->getID()));
     return $result;
 }
 public function render()
 {
     $handles = $this->handles;
     require_celerity_resource('maniphest-task-summary-css');
     $list = new PHUIObjectItemListView();
     if ($this->noDataString) {
         $list->setNoDataString($this->noDataString);
     } else {
         $list->setNoDataString(pht('No tasks.'));
     }
     $status_map = ManiphestTaskStatus::getTaskStatusMap();
     $color_map = ManiphestTaskPriority::getColorMap();
     $priority_map = ManiphestTaskPriority::getTaskPriorityMap();
     if ($this->showBatchControls) {
         Javelin::initBehavior('maniphest-list-editor');
     }
     foreach ($this->tasks as $task) {
         $item = id(new PHUIObjectItemView())->setUser($this->getUser())->setObject($task)->setObjectName('T' . $task->getID())->setHeader($task->getTitle())->setHref('/T' . $task->getID());
         if ($task->getOwnerPHID()) {
             $owner = $handles[$task->getOwnerPHID()];
             $item->addByline(pht('Assigned: %s', $owner->renderLink()));
         }
         $status = $task->getStatus();
         $pri = idx($priority_map, $task->getPriority());
         $status_name = idx($status_map, $task->getStatus());
         $tooltip = pht('%s, %s', $status_name, $pri);
         $icon = ManiphestTaskStatus::getStatusIcon($task->getStatus());
         $color = idx($color_map, $task->getPriority(), 'grey');
         if ($task->isClosed()) {
             $item->setDisabled(true);
             $color = 'grey';
         }
         $item->setStatusIcon($icon . ' ' . $color, $tooltip);
         $item->addIcon('none', phabricator_datetime($task->getDateModified(), $this->getUser()));
         if ($this->showSubpriorityControls) {
             $item->setGrippable(true);
         }
         if ($this->showSubpriorityControls || $this->showBatchControls) {
             $item->addSigil('maniphest-task');
         }
         $project_handles = array_select_keys($handles, array_reverse($task->getProjectPHIDs()));
         $item->addAttribute(id(new PHUIHandleTagListView())->setLimit(4)->setNoDataString(pht('No Projects'))->setSlim(true)->setHandles($project_handles));
         $item->setMetadata(array('taskID' => $task->getID()));
         if ($this->showBatchControls) {
             $href = new PhutilURI('/maniphest/task/edit/' . $task->getID() . '/');
             if (!$this->showSubpriorityControls) {
                 $href->setQueryParam('ungrippable', 'true');
             }
             $item->addAction(id(new PHUIListItemView())->setIcon('fa-pencil')->addSigil('maniphest-edit-task')->setHref($href));
         }
         $list->addItem($item);
     }
     return $list;
 }
 public function render()
 {
     if (!$this->user) {
         throw new Exception("Call setUser() before rendering!");
     }
     $task = $this->task;
     $handles = $this->handles;
     require_celerity_resource('maniphest-task-summary-css');
     $classes = array(ManiphestTaskPriority::PRIORITY_UNBREAK_NOW => 'pri-unbreak', ManiphestTaskPriority::PRIORITY_TRIAGE => 'pri-triage', ManiphestTaskPriority::PRIORITY_HIGH => 'pri-high', ManiphestTaskPriority::PRIORITY_NORMAL => 'pri-normal', ManiphestTaskPriority::PRIORITY_LOW => 'pri-low', ManiphestTaskPriority::PRIORITY_WISH => 'pri-wish');
     $pri_class = idx($classes, $task->getPriority());
     return '<table class="maniphest-task-summary">' . '<tr>' . '<td class="maniphest-task-number ' . $pri_class . '">' . 'T' . $task->getID() . '</td>' . '<td class="maniphest-task-status">' . ($task->getStatus() == ManiphestTaskStatus::STATUS_OPEN ? 'Open' : 'Closed') . '</td>' . '<td class="maniphest-task-owner">' . ($task->getOwnerPHID() ? $handles[$task->getOwnerPHID()]->renderLink() : '<em>None</em>') . '</td>' . '<td class="maniphest-task-name">' . phutil_render_tag('a', array('href' => '/T' . $task->getID()), phutil_escape_html($task->getTitle())) . '</td>' . '<td class="maniphest-task-priority">' . ManiphestTaskPriority::getTaskPriorityName($task->getPriority()) . '</td>' . '<td class="maniphest-task-updated">' . phabricator_datetime($task->getDateModified(), $this->user) . '</td>' . '</tr>' . '</table>';
 }
 public function loadResults()
 {
     $viewer = $this->getViewer();
     $raw_query = $this->getRawQuery();
     $results = array();
     $priority_map = ManiphestTaskPriority::getTaskPriorityMap();
     foreach ($priority_map as $value => $name) {
         // NOTE: $value is not a PHID but is unique. This'll work.
         $results[] = id(new PhabricatorTypeaheadResult())->setPHID($value)->setName($name);
     }
     return $results;
 }
 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 getItem()
 {
     $task = $this->getTask();
     $owner = $this->getOwner();
     $can_edit = $this->getCanEdit();
     $color_map = ManiphestTaskPriority::getColorMap();
     $bar_color = idx($color_map, $task->getPriority(), 'grey');
     $card = id(new PHUIObjectItemView())->setObjectName('T' . $task->getID())->setHeader($task->getTitle())->setGrippable($can_edit)->setHref('/T' . $task->getID())->addSigil('project-card')->setDisabled($task->isClosed())->setMetadata(array('objectPHID' => $task->getPHID()))->addAction(id(new PHUIListItemView())->setName(pht('Edit'))->setIcon('fa-pencil')->addSigil('edit-project-card')->setHref('/maniphest/task/edit/' . $task->getID() . '/'))->setBarColor($bar_color);
     if ($owner) {
         $card->addAttribute($owner->renderLink());
     }
     return $card;
 }
 private function buildResults()
 {
     $results = array();
     $priority_map = ManiphestTaskPriority::getTaskPriorityMap();
     foreach ($priority_map as $value => $name) {
         $result = id(new PhabricatorTypeaheadResult())->setIcon(ManiphestTaskPriority::getTaskPriorityIcon($value))->setPHID($value)->setName($name)->addAttribute(pht('Priority'));
         if (ManiphestTaskPriority::isDisabledPriority($value)) {
             $result->setClosed(pht('Disabled'));
         }
         $results[$value] = $result;
     }
     return $results;
 }
 public function renderHovercard(PhabricatorHovercardView $hovercard, PhabricatorObjectHandle $handle, $task, $data)
 {
     $viewer = $this->getViewer();
     $hovercard->setTitle($task->getMonogram())->setDetail($task->getTitle());
     $owner_phid = $task->getOwnerPHID();
     if ($owner_phid) {
         $owner = $viewer->renderHandle($owner_phid);
     } else {
         $owner = phutil_tag('em', array(), pht('None'));
     }
     $hovercard->addField(pht('Assigned To'), $owner);
     $hovercard->addField(pht('Priority'), ManiphestTaskPriority::getTaskPriorityName($task->getPriority()));
     $hovercard->addTag(ManiphestView::renderTagForTask($task));
 }
 protected function buildTaskInfoDictionaries(array $tasks)
 {
     if (!$tasks) {
         return array();
     }
     $all_aux = id(new ManiphestTaskAuxiliaryStorage())->loadAllWhere('taskPHID in (%Ls)', mpull($tasks, 'getPHID'));
     $all_aux = mgroup($all_aux, 'getTaskPHID');
     $result = array();
     foreach ($tasks as $task) {
         $auxiliary = idx($all_aux, $task->getPHID(), array());
         $auxiliary = mpull($auxiliary, 'getValue', 'getName');
         $result[$task->getPHID()] = array('id' => $task->getID(), 'phid' => $task->getPHID(), 'authorPHID' => $task->getAuthorPHID(), 'ownerPHID' => $task->getOwnerPHID(), 'ccPHIDs' => $task->getCCPHIDs(), 'status' => $task->getStatus(), 'priority' => ManiphestTaskPriority::getTaskPriorityName($task->getPriority()), 'title' => $task->getTitle(), 'description' => $task->getDescription(), 'projectPHIDs' => $task->getProjectPHIDs(), 'uri' => PhabricatorEnv::getProductionURI('/T' . $task->getID()), 'auxiliary' => $auxiliary, 'objectName' => 'T' . $task->getID(), 'dateCreated' => $task->getDateCreated(), 'dateModified' => $task->getDateModified());
     }
     return $result;
 }
 /**
  * @phutil-external-symbol class PHPExcel
  * @phutil-external-symbol class PHPExcel_IOFactory
  * @phutil-external-symbol class PHPExcel_Style_NumberFormat
  * @phutil-external-symbol class PHPExcel_Cell_DataType
  */
 public function buildWorkbook(PHPExcel $workbook, array $tasks, array $handles, PhabricatorUser $user)
 {
     $sheet = $workbook->setActiveSheetIndex(0);
     $sheet->setTitle(pht('Tasks'));
     $widths = array(null, 15, null, 10, 15, 15, 60, 30, 20, 100);
     foreach ($widths as $col => $width) {
         if ($width !== null) {
             $sheet->getColumnDimension($this->col($col))->setWidth($width);
         }
     }
     $status_map = ManiphestTaskStatus::getTaskStatusMap();
     $pri_map = ManiphestTaskPriority::getTaskPriorityMap();
     $date_format = null;
     $rows = array();
     $rows[] = array(pht('ID'), pht('Owner'), pht('Status'), pht('Priority'), pht('Date Created'), pht('Date Updated'), pht('Deadline'), pht('Title'), pht('Projects'), pht('Description'));
     $is_date = array(false, false, false, false, true, true, true, false, false, false);
     $header_format = array('font' => array('bold' => true));
     foreach ($tasks as $task) {
         $task_owner = null;
         if ($task->getOwnerPHID()) {
             $task_owner = $handles[$task->getOwnerPHID()]->getName();
         }
         $projects = array();
         foreach ($task->getProjectPHIDs() as $phid) {
             $projects[] = $handles[$phid]->getName();
         }
         $projects = implode(', ', $projects);
         $custom_fields = PhabricatorCustomField::getObjectFields($task, PhabricatorCustomField::ROLE_VIEW);
         $custom_fields->setViewer($user)->readFieldsFromStorage($task);
         $fields = $custom_fields->getFields();
         $rows[] = array('T' . $task->getID(), $task_owner, idx($status_map, $task->getStatus(), '?'), idx($pri_map, $task->getPriority(), '?'), $this->computeExcelDate($task->getDateCreated()), $this->computeExcelDate($task->getDateModified()), $this->computeExcelDate($fields['std:maniphest:Deadline']->getValueForStorage()), $task->getTitle(), $projects, id(new PhutilUTF8StringTruncator())->setMaximumBytes(512)->truncateString($task->getDescription()));
     }
     foreach ($rows as $row => $cols) {
         foreach ($cols as $col => $spec) {
             $cell_name = $this->col($col) . ($row + 1);
             $cell = $sheet->setCellValue($cell_name, $spec, $return_cell = true);
             if ($row == 0) {
                 $sheet->getStyle($cell_name)->applyFromArray($header_format);
             }
             if ($is_date[$col]) {
                 $code = PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2;
                 $sheet->getStyle($cell_name)->getNumberFormat()->setFormatCode($code);
             } else {
                 $cell->setDataType(PHPExcel_Cell_DataType::TYPE_STRING);
             }
         }
     }
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $task_ids = $request->getArr('batch');
     $tasks = id(new ManiphestTask())->loadAllWhere('id IN (%Ld)', $task_ids);
     $actions = $request->getStr('actions');
     if ($actions) {
         $actions = json_decode($actions, true);
     }
     if ($request->isFormPost() && is_array($actions)) {
         foreach ($tasks as $task) {
             $xactions = $this->buildTransactions($actions, $task);
             if ($xactions) {
                 $editor = new ManiphestTransactionEditor();
                 $editor->applyTransactions($task, $xactions);
             }
         }
         $task_ids = implode(',', mpull($tasks, 'getID'));
         return id(new AphrontRedirectResponse())->setURI('/maniphest/view/custom/?s=oc&tasks=' . $task_ids);
     }
     $panel = new AphrontPanelView();
     $panel->setHeader('Maniphest Batch Editor');
     $handle_phids = mpull($tasks, 'getOwnerPHID');
     $handles = id(new PhabricatorObjectHandleData($handle_phids))->loadHandles();
     $list = new ManiphestTaskListView();
     $list->setTasks($tasks);
     $list->setUser($user);
     $list->setHandles($handles);
     $template = new AphrontTokenizerTemplateView();
     $template = $template->render();
     require_celerity_resource('maniphest-batch-editor');
     Javelin::initBehavior('maniphest-batch-editor', array('root' => 'maniphest-batch-edit-form', 'tokenizerTemplate' => $template, 'sources' => array('project' => array('src' => '/typeahead/common/projects/', 'placeholder' => 'Type a project name...'), 'owner' => array('src' => '/typeahead/common/searchowner/', 'placeholder' => 'Type a user name...', 'limit' => 1)), '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_render_tag('input', array('type' => 'hidden', 'name' => 'batch[]', 'value' => $task->getID()), null));
     }
     $form->appendChild(phutil_render_tag('input', array('type' => 'hidden', 'name' => 'actions', 'id' => 'batch-form-actions'), null));
     $form->appendChild('<p>These tasks will be edited:</p>');
     $form->appendChild($list);
     $form->appendChild(id(new AphrontFormInsetView())->setTitle('Actions')->setRightButton(javelin_render_tag('a', array('href' => '#', 'class' => 'button green', 'sigil' => 'add-action', 'mustcapture' => true), 'Add Another Action'))->setContent(javelin_render_tag('table', array('sigil' => 'maniphest-batch-actions', 'class' => 'maniphest-batch-actions-table'), '')))->appendChild(id(new AphrontFormSubmitControl())->setValue('Update Tasks')->addCancelButton('/maniphest/', 'Done'));
     $panel->appendChild($form);
     return $this->buildStandardPageResponse($panel, array('title' => 'Batch Editor'));
 }
 public function getItem()
 {
     $task = $this->getTask();
     $owner = $this->getOwner();
     $can_edit = $this->getCanEdit();
     $viewer = $this->getViewer();
     $color_map = ManiphestTaskPriority::getColorMap();
     $bar_color = idx($color_map, $task->getPriority(), 'grey');
     $card = id(new PHUIObjectItemView())->setObject($task)->setUser($viewer)->setObjectName('T' . $task->getID())->setHeader($task->getTitle())->setGrippable($can_edit)->setHref('/T' . $task->getID())->addSigil('project-card')->setDisabled($task->isClosed())->addAction(id(new PHUIListItemView())->setName(pht('Edit'))->setIcon('fa-pencil')->addSigil('edit-project-card')->setHref('/maniphest/task/edit/' . $task->getID() . '/'))->setBarColor($bar_color);
     if ($owner) {
         $card->addHandleIcon($owner, $owner->getName());
     }
     $cover_file = $this->getCoverImageFile();
     if ($cover_file) {
         $card->setCoverImage($cover_file->getBestURI());
     }
     if (ManiphestTaskPoints::getIsEnabled()) {
         $points = $task->getPoints();
         if ($points !== null) {
             $points_tag = id(new PHUITagView())->setType(PHUITagView::TYPE_SHADE)->setShade(PHUITagView::COLOR_GREY)->setSlimShady(true)->setName($points)->addClass('phui-workcard-points');
             $card->addAttribute($points_tag);
         }
     }
     if ($task->isClosed()) {
         $icon = ManiphestTaskStatus::getStatusIcon($task->getStatus());
         $icon = id(new PHUIIconView())->setIcon($icon . ' grey');
         $card->addAttribute($icon);
         $card->setBarColor('grey');
     }
     $project_handles = $this->getProjectHandles();
     // Remove any archived projects from the list.
     if ($project_handles) {
         foreach ($project_handles as $key => $handle) {
             if ($handle->getStatus() == PhabricatorObjectHandle::STATUS_CLOSED) {
                 unset($project_handles[$key]);
             }
         }
     }
     if ($project_handles) {
         $project_handles = array_reverse($project_handles);
         $tag_list = id(new PHUIHandleTagListView())->setSlim(true)->setHandles($project_handles);
         $card->addAttribute($tag_list);
     }
     $card->addClass('phui-workcard');
     return $card;
 }
 private function handleHovercardEvent(PhutilEvent $event)
 {
     $viewer = $event->getUser();
     $hovercard = $event->getValue('hovercard');
     $handle = $event->getValue('handle');
     $phid = $handle->getPHID();
     $task = $event->getValue('object');
     if (!$task instanceof ManiphestTask) {
         return;
     }
     $e_project = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
     // Fun with "Unbeta Pholio", hua hua
     $e_dep_on = ManiphestTaskDependsOnTaskEdgeType::EDGECONST;
     $e_dep_by = ManiphestTaskDependedOnByTaskEdgeType::EDGECONST;
     $edge_query = id(new PhabricatorEdgeQuery())->withSourcePHIDs(array($phid))->withEdgeTypes(array($e_project, $e_dep_on, $e_dep_by));
     $edges = idx($edge_query->execute(), $phid);
     $edge_phids = $edge_query->getDestinationPHIDs();
     $owner_phid = $task->getOwnerPHID();
     $hovercard->setTitle(pht('T%d', $task->getID()))->setDetail($task->getTitle());
     if ($owner_phid) {
         $owner = $viewer->renderHandle($owner_phid);
     } else {
         $owner = phutil_tag('em', array(), pht('None'));
     }
     $hovercard->addField(pht('Assigned To'), $owner);
     $hovercard->addField(pht('Priority'), ManiphestTaskPriority::getTaskPriorityName($task->getPriority()));
     if ($edge_phids) {
         $edge_types = array($e_project => pht('Projects'), $e_dep_by => pht('Blocks'), $e_dep_on => pht('Blocked By'));
         $max_count = 6;
         foreach ($edge_types as $edge_type => $edge_name) {
             if ($edges[$edge_type]) {
                 // TODO: This can be made more sophisticated. We still load all
                 // edges into memory. Only load the ones we need.
                 $edge_overflow = array();
                 if (count($edges[$edge_type]) > $max_count) {
                     $edges[$edge_type] = array_slice($edges[$edge_type], 0, 6, true);
                     $edge_overflow = ', ...';
                 }
                 $hovercard->addField($edge_name, array($viewer->renderHandleList(array_keys($edges[$edge_type])), $edge_overflow));
             }
         }
     }
     $hovercard->addTag(ManiphestView::renderTagForTask($task));
     $event->setValue('hovercard', $hovercard);
 }
 public function getItem()
 {
     require_celerity_resource('phui-workboard-view-css', 'sprint');
     $query = id(new SprintQuery())->setProject($this->project)->setViewer($this->viewer);
     $task = $this->getTask();
     $task_phid = $task->getPHID();
     $can_edit = $this->getCanEdit();
     $this->points = $query->getStoryPointsForTask($task_phid);
     $color_map = ManiphestTaskPriority::getColorMap();
     $bar_color = idx($color_map, $task->getPriority(), 'grey');
     if (!is_null($this->owner)) {
         $ownerimage = $this->renderHandleIcon($this->owner);
     } else {
         $ownerimage = null;
     }
     $card = id(new PHUIObjectItemView())->setObjectName('T' . $task->getID())->setHeader($task->getTitle())->setGrippable($can_edit)->setHref('/T' . $task->getID())->addSigil('project-card')->setDisabled($task->isClosed())->setImageIcon($ownerimage)->setMetadata(array('objectPHID' => $task_phid, 'taskNodeID' => $this->task_node_id, 'points' => $this->points))->addAction(id(new PHUIListItemView())->setName(pht('Edit'))->setIcon('fa-pencil')->addSigil('edit-project-card')->setHref('/project/sprint/board/task/edit/' . $task->getID() . '/'))->setBarColor($bar_color)->addAttribute($this->getCardAttributes());
     return $card;
 }
 public function getItem()
 {
     require_celerity_resource('phui-workboard-view-css', 'sprint');
     $query = id(new SprintQuery())->setProject($this->project)->setViewer($this->viewer);
     $task = $this->getTask();
     $task_phid = $task->getPHID();
     $can_edit = $this->getCanEdit();
     $this->points = $query->getStoryPointsForTask($task_phid);
     $color_map = ManiphestTaskPriority::getColorMap();
     $bar_color = idx($color_map, $task->getPriority(), 'grey');
     if (!is_null($this->owner)) {
         $ownerimage = $this->renderHandleIcon($this->owner);
     } else {
         $ownerimage = null;
     }
     $card = id(new PHUIObjectItemView())->setObjectName('T' . $task->getID())->setHeader($task->getTitle())->setGrippable($can_edit)->setHref('/T' . $task->getID())->addSigil('project-card')->setDisabled($task->isClosed())->setImageIcon($ownerimage)->setMetadata(array('objectPHID' => $task_phid, 'taskNodeID' => $this->task_node_id, 'points' => $this->points))->addAction(id(new PHUIListItemView())->setName(pht('Edit'))->setIcon('fa-pencil')->addSigil('edit-project-card')->setHref('/project/sprint/board/task/edit/' . $task->getID() . '/'))->setBarColor($bar_color)->addAttribute($this->getCardAttributes());
     $continue_title = "";
     $continue_icon = "";
     switch ($task->getStatus()) {
         case "open":
             $continue_title = "Start";
             $continue_icon = "fa-play";
             break;
         case "inprogress":
             $continue_title = "Finish";
             $continue_icon = "fa-flag-checkered";
             break;
         case "finished":
             $continue_title = "Deliver";
             $continue_icon = "fa-truck";
             break;
         case "delivered":
             $continue_title = "Accept";
             $continue_icon = "fa-thumbs-up";
             break;
     }
     if ($continue_title != "") {
         $card->addAction(id(new PHUIListItemView())->setName(pht($continue_title))->setIcon($continue_icon)->addSigil('continue-project-card')->setHref('/project/sprint/board/task/continue/' . $task->getID() . '/'));
     }
     if ($task->getStatus() == 'delivered') {
         $card->addAction(id(new PHUIListItemView())->setName(pht("Reject"))->setIcon('fa-thumbs-down')->addSigil('reject-project-card')->setHref('/project/sprint/board/task/continue/' . $task->getID() . '/'));
     }
     return $card;
 }
 protected function newTableRow($phid, $object, $trace)
 {
     $viewer = $this->getViewer();
     if ($object) {
         $status = $object->getStatus();
         $priority = $object->getPriority();
         $status_icon = ManiphestTaskStatus::getStatusIcon($status);
         $status_name = ManiphestTaskStatus::getTaskStatusName($status);
         $priority_color = ManiphestTaskPriority::getTaskPriorityColor($priority);
         if ($object->isClosed()) {
             $priority_color = 'grey';
         }
         $status = array(id(new PHUIIconView())->setIcon($status_icon, $priority_color), ' ', $status_name);
         $owner_phid = $object->getOwnerPHID();
         if ($owner_phid) {
             $assigned = $viewer->renderHandle($owner_phid);
         } else {
             $assigned = phutil_tag('em', array(), pht('None'));
         }
         $full_title = $object->getTitle();
         $title = id(new PhutilUTF8StringTruncator())->setMaximumGlyphs(80)->truncateString($full_title);
         $link = phutil_tag('a', array('href' => $object->getURI(), 'title' => $full_title), $title);
         $link = array(phutil_tag('span', array('class' => 'object-name'), $object->getMonogram()), ' ', $link);
     } else {
         $status = null;
         $assigned = null;
         $link = $viewer->renderHandle($phid);
     }
     if ($this->isParentTask($phid)) {
         $marker = 'fa-chevron-circle-up bluegrey';
         $marker_tip = pht('Direct Parent');
     } else {
         if ($this->isChildTask($phid)) {
             $marker = 'fa-chevron-circle-down bluegrey';
             $marker_tip = pht('Direct Subtask');
         } else {
             $marker = null;
         }
     }
     if ($marker) {
         $marker = id(new PHUIIconView())->setIcon($marker)->addSigil('has-tooltip')->setMetadata(array('tip' => $marker_tip, 'align' => 'E'));
     }
     return array($marker, $trace, $status, $assigned, $link);
 }
 private function buildHeaderView(ManiphestTask $task)
 {
     $view = id(new PHUIHeaderView())->setHeader($task->getTitle())->setUser($this->getRequest()->getUser())->setPolicyObject($task);
     $priority_name = ManiphestTaskPriority::getTaskPriorityName($task->getPriority());
     $priority_color = ManiphestTaskPriority::getTaskPriorityColor($task->getPriority());
     $status = $task->getStatus();
     $status_name = ManiphestTaskStatus::renderFullDescription($status, $priority_name, $priority_color);
     $view->addProperty(PHUIHeaderView::PROPERTY_STATUS, $status_name);
     $view->setHeaderIcon(ManiphestTaskStatus::getStatusIcon($task->getStatus()) . ' ' . $priority_color);
     if (ManiphestTaskPoints::getIsEnabled()) {
         $points = $task->getPoints();
         if ($points !== null) {
             $points_name = pht('%s %s', $task->getPoints(), ManiphestTaskPoints::getPointsLabel());
             $tag = id(new PHUITagView())->setName($points_name)->setShade('blue')->setType(PHUITagView::TYPE_SHADE);
             $view->addTag($tag);
         }
     }
     return $view;
 }
 public function buildTransactions(PhabricatorUser $viewer, PhabricatorApplicationTransactionInterface $object, PhabricatorMetaMTAReceivedMail $mail, $command, array $argv)
 {
     $xactions = array();
     $target = phutil_utf8_strtolower(head($argv));
     $priority = null;
     $keywords = ManiphestTaskPriority::getTaskPriorityKeywordsMap();
     foreach ($keywords as $key => $words) {
         foreach ($words as $word) {
             if ($word == $target) {
                 $priority = $key;
                 break;
             }
         }
     }
     if ($priority === null) {
         return array();
     }
     $xactions[] = $object->getApplicationTransactionTemplate()->setTransactionType(ManiphestTransaction::TYPE_PRIORITY)->setNewValue($priority);
     return $xactions;
 }
 public function getItem()
 {
     $task = $this->getTask();
     $owner = $this->getOwner();
     $can_edit = $this->getCanEdit();
     $viewer = $this->getViewer();
     $color_map = ManiphestTaskPriority::getColorMap();
     $bar_color = idx($color_map, $task->getPriority(), 'grey');
     $card = id(new PHUIObjectItemView())->setObject($task)->setUser($viewer)->setObjectName('T' . $task->getID())->setHeader($task->getTitle())->setGrippable($can_edit)->setHref('/T' . $task->getID())->addSigil('project-card')->setDisabled($task->isClosed())->setMetadata(array('objectPHID' => $task->getPHID()))->addAction(id(new PHUIListItemView())->setName(pht('Edit'))->setIcon('fa-pencil')->addSigil('edit-project-card')->setHref('/maniphest/task/edit/' . $task->getID() . '/'))->setBarColor($bar_color);
     if ($owner) {
         $card->addAttribute($owner->renderLink());
     }
     $project_phids = array_fuse($task->getProjectPHIDs());
     unset($project_phids[$this->project->getPHID()]);
     if ($project_phids) {
         $handle_list = $viewer->loadHandles($project_phids);
         $tag_list = id(new PHUIHandleTagListView())->setSlim(true)->setHandles($handle_list);
         $card->addAttribute($tag_list);
     }
     return $card;
 }
 private function loadTasks(array $user_phids, array $project_phids, array $task_ids, array $dict)
 {
     $query = new ManiphestTaskQuery();
     $query->withProjects($project_phids);
     $query->withTaskIDs($task_ids);
     $status = $dict['status'];
     if (!empty($status['open']) && !empty($status['closed'])) {
         $query->withStatus(ManiphestTaskQuery::STATUS_ANY);
     } else {
         if (!empty($status['open'])) {
             $query->withStatus(ManiphestTaskQuery::STATUS_OPEN);
         } else {
             $query->withStatus(ManiphestTaskQuery::STATUS_CLOSED);
         }
     }
     switch ($this->view) {
         case 'action':
             $query->withOwners($user_phids);
             break;
         case 'created':
             $query->withAuthors($user_phids);
             break;
         case 'subscribed':
             $query->withSubscribers($user_phids);
             break;
         case 'triage':
             $query->withOwners($user_phids);
             $query->withPriority(ManiphestTaskPriority::PRIORITY_TRIAGE);
             break;
         case 'alltriage':
             $query->withPriority(ManiphestTaskPriority::PRIORITY_TRIAGE);
             break;
         case 'all':
             break;
     }
     $order_map = array('priority' => ManiphestTaskQuery::ORDER_PRIORITY, 'created' => ManiphestTaskQuery::ORDER_CREATED);
     $query->setOrderBy(idx($order_map, $dict['order'], ManiphestTaskQuery::ORDER_MODIFIED));
     $group_map = array('priority' => ManiphestTaskQuery::GROUP_PRIORITY, 'owner' => ManiphestTaskQuery::GROUP_OWNER, 'status' => ManiphestTaskQuery::GROUP_STATUS);
     $query->setGroupBy(idx($group_map, $dict['group'], ManiphestTaskQuery::GROUP_NONE));
     $query->setCalculateRows(true);
     $query->setLimit($dict['limit']);
     $query->setOffset($dict['offset']);
     $data = $query->execute();
     $total_row_count = $query->getRowCount();
     $handle_phids = mpull($data, 'getOwnerPHID');
     $handle_phids = array_merge($handle_phids, $project_phids, $user_phids);
     $handles = id(new PhabricatorObjectHandleData($handle_phids))->loadHandles();
     switch ($dict['group']) {
         case 'priority':
             $data = mgroup($data, 'getPriority');
             krsort($data);
             // If we have invalid priorities, they'll all map to "???". Merge
             // arrays to prevent them from overwriting each other.
             $out = array();
             foreach ($data as $pri => $tasks) {
                 $out[ManiphestTaskPriority::getTaskPriorityName($pri)][] = $tasks;
             }
             foreach ($out as $pri => $tasks) {
                 $out[$pri] = array_mergev($tasks);
             }
             $data = $out;
             break;
         case 'status':
             $data = mgroup($data, 'getStatus');
             ksort($data);
             $out = array();
             foreach ($data as $status => $tasks) {
                 $out[ManiphestTaskStatus::getTaskStatusFullName($status)] = $tasks;
             }
             $data = $out;
             break;
         case 'owner':
             $data = mgroup($data, 'getOwnerPHID');
             $out = array();
             foreach ($data as $phid => $tasks) {
                 if ($phid) {
                     $out[$handles[$phid]->getFullName()] = $tasks;
                 } else {
                     $out['Unassigned'] = $tasks;
                 }
             }
             if (isset($out['Unassigned'])) {
                 // If any tasks are unassigned, move them to the front of the list.
                 $data = array('Unassigned' => $out['Unassigned']) + $out;
             } else {
                 $data = $out;
             }
             ksort($data);
             break;
         default:
             $data = array('Tasks' => $data);
             break;
     }
     return array($data, $handles, $total_row_count);
 }
 public function renderOpenTasks()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $query = id(new ManiphestTaskQuery())->withStatus(ManiphestTaskQuery::STATUS_OPEN);
     $project_phid = $request->getStr('project');
     $project_handle = null;
     if ($project_phid) {
         $phids = array($project_phid);
         $handles = $this->loadViewerHandles($phids);
         $project_handle = $handles[$project_phid];
         $query->withAnyProjects($phids);
     }
     $tasks = $query->execute();
     $recently_closed = $this->loadRecentlyClosedTasks();
     $date = phabricator_date(time(), $user);
     switch ($this->view) {
         case 'user':
             $result = mgroup($tasks, 'getOwnerPHID');
             $leftover = idx($result, '', array());
             unset($result['']);
             $result_closed = mgroup($recently_closed, 'getOwnerPHID');
             $leftover_closed = idx($result_closed, '', array());
             unset($result_closed['']);
             $base_link = '/maniphest/?users=';
             $leftover_name = phutil_render_tag('a', array('href' => $base_link . ManiphestTaskOwner::OWNER_UP_FOR_GRABS), '<em>(Up For Grabs)</em>');
             $col_header = 'User';
             $header = 'Open Tasks by User and Priority (' . $date . ')';
             break;
         case 'project':
             $result = array();
             $leftover = array();
             foreach ($tasks as $task) {
                 $phids = $task->getProjectPHIDs();
                 if ($phids) {
                     foreach ($phids as $project_phid) {
                         $result[$project_phid][] = $task;
                     }
                 } else {
                     $leftover[] = $task;
                 }
             }
             $result_closed = array();
             $leftover_closed = array();
             foreach ($recently_closed as $task) {
                 $phids = $task->getProjectPHIDs();
                 if ($phids) {
                     foreach ($phids as $project_phid) {
                         $result_closed[$project_phid][] = $task;
                     }
                 } else {
                     $leftover_closed[] = $task;
                 }
             }
             $base_link = '/maniphest/view/all/?projects=';
             $leftover_name = phutil_render_tag('a', array('href' => $base_link . ManiphestTaskOwner::PROJECT_NO_PROJECT), '<em>(No Project)</em>');
             $col_header = 'Project';
             $header = 'Open Tasks by Project and Priority (' . $date . ')';
             break;
     }
     $phids = array_keys($result);
     $handles = $this->loadViewerHandles($phids);
     $handles = msort($handles, 'getName');
     $order = $request->getStr('order', 'name');
     list($order, $reverse) = AphrontTableView::parseSort($order);
     require_celerity_resource('aphront-tooltip-css');
     Javelin::initBehavior('phabricator-tooltips', array());
     $rows = array();
     $pri_total = array();
     foreach (array_merge($handles, array(null)) as $handle) {
         if ($handle) {
             if ($project_handle && $project_handle->getPHID() == $handle->getPHID()) {
                 // If filtering by, e.g., "bugs", don't show a "bugs" group.
                 continue;
             }
             $tasks = idx($result, $handle->getPHID(), array());
             $name = phutil_render_tag('a', array('href' => $base_link . $handle->getPHID()), phutil_escape_html($handle->getName()));
             $closed = idx($result_closed, $handle->getPHID(), array());
         } else {
             $tasks = $leftover;
             $name = $leftover_name;
             $closed = $leftover_closed;
         }
         $taskv = $tasks;
         $tasks = mgroup($tasks, 'getPriority');
         $row = array();
         $row[] = $name;
         $total = 0;
         foreach (ManiphestTaskPriority::getTaskPriorityMap() as $pri => $label) {
             $n = count(idx($tasks, $pri, array()));
             if ($n == 0) {
                 $row[] = '-';
             } else {
                 $row[] = number_format($n);
             }
             $total += $n;
         }
         $row[] = number_format($total);
         list($link, $oldest_all) = $this->renderOldest($taskv);
         $row[] = $link;
         $normal_or_better = array();
         foreach ($taskv as $id => $task) {
             if ($task->getPriority() < ManiphestTaskPriority::PRIORITY_NORMAL) {
                 continue;
             }
             $normal_or_better[$id] = $task;
         }
         list($link, $oldest_pri) = $this->renderOldest($normal_or_better);
         $row[] = $link;
         if ($closed) {
             $task_ids = implode(',', mpull($closed, 'getID'));
             $row[] = phutil_render_tag('a', array('href' => '/maniphest/view/custom/?s=oc&tasks=' . $task_ids, 'target' => '_blank'), phutil_escape_html(number_format(count($closed))));
         } else {
             $row[] = '-';
         }
         switch ($order) {
             case 'total':
                 $row['sort'] = $total;
                 break;
             case 'oldest-all':
                 $row['sort'] = $oldest_all;
                 break;
             case 'oldest-pri':
                 $row['sort'] = $oldest_pri;
                 break;
             case 'closed':
                 $row['sort'] = count($closed);
                 break;
             case 'name':
             default:
                 $row['sort'] = $handle ? $handle->getName() : '~';
                 break;
         }
         $rows[] = $row;
     }
     $rows = isort($rows, 'sort');
     foreach ($rows as $k => $row) {
         unset($rows[$k]['sort']);
     }
     if ($reverse) {
         $rows = array_reverse($rows);
     }
     $cname = array($col_header);
     $cclass = array('pri right wide');
     $pri_map = ManiphestTaskPriority::getTaskBriefPriorityMap();
     foreach ($pri_map as $pri => $label) {
         $cname[] = $label;
         $cclass[] = 'n';
     }
     $cname[] = 'Total';
     $cclass[] = 'n';
     $cname[] = javelin_render_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => 'Oldest open task.', 'size' => 200)), 'Oldest (All)');
     $cclass[] = 'n';
     $cname[] = javelin_render_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => 'Oldest open task, excluding those with Low or Wishlist ' . 'priority.', 'size' => 200)), 'Oldest (Pri)');
     $cclass[] = 'n';
     list($ignored, $window_epoch) = $this->getWindow();
     $cname[] = javelin_render_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => 'Closed after ' . phabricator_datetime($window_epoch, $user), 'size' => 260)), 'Recently Closed');
     $cclass[] = 'n';
     $table = new AphrontTableView($rows);
     $table->setHeaders($cname);
     $table->setColumnClasses($cclass);
     $table->makeSortable($request->getRequestURI(), 'order', $order, $reverse, array('name', null, null, null, null, null, null, 'total', 'oldest-all', 'oldest-pri', 'closed'));
     $panel = new AphrontPanelView();
     $panel->setHeader($header);
     $panel->appendChild($table);
     $tokens = array();
     if ($project_handle) {
         $tokens = array($project_handle->getPHID() => $project_handle->getFullName());
     }
     $filter = $this->renderReportFilters($tokens, $has_window = true);
     return array($filter, $panel);
 }
 public static function loadTasks(PhabricatorSearchQuery $search_query)
 {
     $any_project = false;
     $search_text = $search_query->getParameter('fullTextSearch');
     $user_phids = $search_query->getParameter('userPHIDs', array());
     $project_phids = $search_query->getParameter('projectPHIDs', array());
     $task_ids = $search_query->getParameter('taskIDs', array());
     $xproject_phids = $search_query->getParameter('excludeProjectPHIDs', array());
     $owner_phids = $search_query->getParameter('ownerPHIDs', array());
     $author_phids = $search_query->getParameter('authorPHIDs', array());
     $low_priority = $search_query->getParameter('lowPriority');
     $low_priority = nonempty($low_priority, ManiphestTaskPriority::getLowestPriority());
     $high_priority = $search_query->getParameter('highPriority');
     $high_priority = nonempty($high_priority, ManiphestTaskPriority::getHighestPriority());
     $query = new ManiphestTaskQuery();
     $query->withProjects($project_phids);
     $query->withTaskIDs($task_ids);
     if ($xproject_phids) {
         $query->withoutProjects($xproject_phids);
     }
     if ($owner_phids) {
         $query->withOwners($owner_phids);
     }
     if ($author_phids) {
         $query->withAuthors($author_phids);
     }
     $status = $search_query->getParameter('status', 'all');
     if (!empty($status['open']) && !empty($status['closed'])) {
         $query->withStatus(ManiphestTaskQuery::STATUS_ANY);
     } else {
         if (!empty($status['open'])) {
             $query->withStatus(ManiphestTaskQuery::STATUS_OPEN);
         } else {
             $query->withStatus(ManiphestTaskQuery::STATUS_CLOSED);
         }
     }
     switch ($search_query->getParameter('view')) {
         case 'action':
             $query->withOwners($user_phids);
             break;
         case 'created':
             $query->withAuthors($user_phids);
             break;
         case 'subscribed':
             $query->withSubscribers($user_phids);
             break;
         case 'triage':
             $query->withOwners($user_phids);
             $query->withPriority(ManiphestTaskPriority::PRIORITY_TRIAGE);
             break;
         case 'alltriage':
             $query->withPriority(ManiphestTaskPriority::PRIORITY_TRIAGE);
             break;
         case 'all':
             break;
         case 'projecttriage':
             $query->withPriority(ManiphestTaskPriority::PRIORITY_TRIAGE);
             $any_project = true;
             break;
         case 'projectall':
             $any_project = true;
             break;
         case 'custom':
             $query->withPrioritiesBetween($low_priority, $high_priority);
             break;
     }
     $query->withAnyProject($any_project);
     $query->withFullTextSearch($search_text);
     $order_map = array('priority' => ManiphestTaskQuery::ORDER_PRIORITY, 'created' => ManiphestTaskQuery::ORDER_CREATED, 'title' => ManiphestTaskQuery::ORDER_TITLE);
     $query->setOrderBy(idx($order_map, $search_query->getParameter('order'), ManiphestTaskQuery::ORDER_MODIFIED));
     $group_map = array('priority' => ManiphestTaskQuery::GROUP_PRIORITY, 'owner' => ManiphestTaskQuery::GROUP_OWNER, 'status' => ManiphestTaskQuery::GROUP_STATUS, 'project' => ManiphestTaskQuery::GROUP_PROJECT);
     $query->setGroupBy(idx($group_map, $search_query->getParameter('group'), ManiphestTaskQuery::GROUP_NONE));
     $query->setCalculateRows(true);
     $query->setLimit($search_query->getParameter('limit'));
     $query->setOffset($search_query->getParameter('offset'));
     $data = $query->execute();
     $total_row_count = $query->getRowCount();
     $project_group_phids = array();
     if ($search_query->getParameter('group') == 'project') {
         foreach ($data as $task) {
             foreach ($task->getProjectPHIDs() as $phid) {
                 $project_group_phids[] = $phid;
             }
         }
     }
     $handle_phids = mpull($data, 'getOwnerPHID');
     $handle_phids = array_merge($handle_phids, $project_phids, $user_phids, $xproject_phids, $owner_phids, $author_phids, $project_group_phids, array_mergev(mpull($data, 'getProjectPHIDs')));
     $handles = id(new PhabricatorObjectHandleData($handle_phids))->loadHandles();
     switch ($search_query->getParameter('group')) {
         case 'priority':
             $data = mgroup($data, 'getPriority');
             // If we have invalid priorities, they'll all map to "???". Merge
             // arrays to prevent them from overwriting each other.
             $out = array();
             foreach ($data as $pri => $tasks) {
                 $out[ManiphestTaskPriority::getTaskPriorityName($pri)][] = $tasks;
             }
             foreach ($out as $pri => $tasks) {
                 $out[$pri] = array_mergev($tasks);
             }
             $data = $out;
             break;
         case 'status':
             $data = mgroup($data, 'getStatus');
             $out = array();
             foreach ($data as $status => $tasks) {
                 $out[ManiphestTaskStatus::getTaskStatusFullName($status)] = $tasks;
             }
             $data = $out;
             break;
         case 'owner':
             $data = mgroup($data, 'getOwnerPHID');
             $out = array();
             foreach ($data as $phid => $tasks) {
                 if ($phid) {
                     $out[$handles[$phid]->getFullName()] = $tasks;
                 } else {
                     $out['Unassigned'] = $tasks;
                 }
             }
             $data = $out;
             ksort($data);
             // Move "Unassigned" to the top of the list.
             if (isset($data['Unassigned'])) {
                 $data = array('Unassigned' => $out['Unassigned']) + $out;
             }
             break;
         case 'project':
             $grouped = array();
             foreach ($query->getGroupByProjectResults() as $project => $tasks) {
                 foreach ($tasks as $task) {
                     $group = $project ? $handles[$project]->getName() : 'No Project';
                     $grouped[$group][$task->getID()] = $task;
                 }
             }
             $data = $grouped;
             ksort($data);
             // Move "No Project" to the end of the list.
             if (isset($data['No Project'])) {
                 $noproject = $data['No Project'];
                 unset($data['No Project']);
                 $data += array('No Project' => $noproject);
             }
             break;
         default:
             $data = array('Tasks' => $data);
             break;
     }
     return array($data, $handles, $total_row_count);
 }
 public function renderOpenTasks()
 {
     $request = $this->getRequest();
     $viewer = $request->getUser();
     $query = id(new ManiphestTaskQuery())->setViewer($viewer)->withStatuses(ManiphestTaskStatus::getOpenStatusConstants());
     switch ($this->view) {
         case 'project':
             $query->needProjectPHIDs(true);
             break;
     }
     $project_phid = $request->getStr('project');
     $project_handle = null;
     if ($project_phid) {
         $phids = array($project_phid);
         $handles = $this->loadViewerHandles($phids);
         $project_handle = $handles[$project_phid];
         $query->withEdgeLogicPHIDs(PhabricatorProjectObjectHasProjectEdgeType::EDGECONST, PhabricatorQueryConstraint::OPERATOR_OR, $phids);
     }
     $tasks = $query->execute();
     $recently_closed = $this->loadRecentlyClosedTasks();
     $date = phabricator_date(time(), $viewer);
     switch ($this->view) {
         case 'user':
             $result = mgroup($tasks, 'getOwnerPHID');
             $leftover = idx($result, '', array());
             unset($result['']);
             $result_closed = mgroup($recently_closed, 'getOwnerPHID');
             $leftover_closed = idx($result_closed, '', array());
             unset($result_closed['']);
             $base_link = '/maniphest/?assigned=';
             $leftover_name = phutil_tag('em', array(), pht('(Up For Grabs)'));
             $col_header = pht('User');
             $header = pht('Open Tasks by User and Priority (%s)', $date);
             break;
         case 'project':
             $result = array();
             $leftover = array();
             foreach ($tasks as $task) {
                 $phids = $task->getProjectPHIDs();
                 if ($phids) {
                     foreach ($phids as $project_phid) {
                         $result[$project_phid][] = $task;
                     }
                 } else {
                     $leftover[] = $task;
                 }
             }
             $result_closed = array();
             $leftover_closed = array();
             foreach ($recently_closed as $task) {
                 $phids = $task->getProjectPHIDs();
                 if ($phids) {
                     foreach ($phids as $project_phid) {
                         $result_closed[$project_phid][] = $task;
                     }
                 } else {
                     $leftover_closed[] = $task;
                 }
             }
             $base_link = '/maniphest/?projects=';
             $leftover_name = phutil_tag('em', array(), pht('(No Project)'));
             $col_header = pht('Project');
             $header = pht('Open Tasks by Project and Priority (%s)', $date);
             break;
     }
     $phids = array_keys($result);
     $handles = $this->loadViewerHandles($phids);
     $handles = msort($handles, 'getName');
     $order = $request->getStr('order', 'name');
     list($order, $reverse) = AphrontTableView::parseSort($order);
     require_celerity_resource('aphront-tooltip-css');
     Javelin::initBehavior('phabricator-tooltips', array());
     $rows = array();
     $pri_total = array();
     foreach (array_merge($handles, array(null)) as $handle) {
         if ($handle) {
             if ($project_handle && $project_handle->getPHID() == $handle->getPHID()) {
                 // If filtering by, e.g., "bugs", don't show a "bugs" group.
                 continue;
             }
             $tasks = idx($result, $handle->getPHID(), array());
             $name = phutil_tag('a', array('href' => $base_link . $handle->getPHID()), $handle->getName());
             $closed = idx($result_closed, $handle->getPHID(), array());
         } else {
             $tasks = $leftover;
             $name = $leftover_name;
             $closed = $leftover_closed;
         }
         $taskv = $tasks;
         $tasks = mgroup($tasks, 'getPriority');
         $row = array();
         $row[] = $name;
         $total = 0;
         foreach (ManiphestTaskPriority::getTaskPriorityMap() as $pri => $label) {
             $n = count(idx($tasks, $pri, array()));
             if ($n == 0) {
                 $row[] = '-';
             } else {
                 $row[] = number_format($n);
             }
             $total += $n;
         }
         $row[] = number_format($total);
         list($link, $oldest_all) = $this->renderOldest($taskv);
         $row[] = $link;
         $normal_or_better = array();
         foreach ($taskv as $id => $task) {
             // TODO: This is sort of a hard-code for the default "normal" status.
             // When reports are more powerful, this should be made more general.
             if ($task->getPriority() < 50) {
                 continue;
             }
             $normal_or_better[$id] = $task;
         }
         list($link, $oldest_pri) = $this->renderOldest($normal_or_better);
         $row[] = $link;
         if ($closed) {
             $task_ids = implode(',', mpull($closed, 'getID'));
             $row[] = phutil_tag('a', array('href' => '/maniphest/?ids=' . $task_ids, 'target' => '_blank'), number_format(count($closed)));
         } else {
             $row[] = '-';
         }
         switch ($order) {
             case 'total':
                 $row['sort'] = $total;
                 break;
             case 'oldest-all':
                 $row['sort'] = $oldest_all;
                 break;
             case 'oldest-pri':
                 $row['sort'] = $oldest_pri;
                 break;
             case 'closed':
                 $row['sort'] = count($closed);
                 break;
             case 'name':
             default:
                 $row['sort'] = $handle ? $handle->getName() : '~';
                 break;
         }
         $rows[] = $row;
     }
     $rows = isort($rows, 'sort');
     foreach ($rows as $k => $row) {
         unset($rows[$k]['sort']);
     }
     if ($reverse) {
         $rows = array_reverse($rows);
     }
     $cname = array($col_header);
     $cclass = array('pri right wide');
     $pri_map = ManiphestTaskPriority::getShortNameMap();
     foreach ($pri_map as $pri => $label) {
         $cname[] = $label;
         $cclass[] = 'n';
     }
     $cname[] = pht('Total');
     $cclass[] = 'n';
     $cname[] = javelin_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => pht('Oldest open task.'), 'size' => 200)), pht('Oldest (All)'));
     $cclass[] = 'n';
     $cname[] = javelin_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => pht('Oldest open task, excluding those with Low or Wishlist priority.'), 'size' => 200)), pht('Oldest (Pri)'));
     $cclass[] = 'n';
     list($ignored, $window_epoch) = $this->getWindow();
     $edate = phabricator_datetime($window_epoch, $viewer);
     $cname[] = javelin_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => pht('Closed after %s', $edate), 'size' => 260)), pht('Recently Closed'));
     $cclass[] = 'n';
     $table = new AphrontTableView($rows);
     $table->setHeaders($cname);
     $table->setColumnClasses($cclass);
     $table->makeSortable($request->getRequestURI(), 'order', $order, $reverse, array('name', null, null, null, null, null, null, 'total', 'oldest-all', 'oldest-pri', 'closed'));
     $panel = new PHUIObjectBoxView();
     $panel->setHeaderText($header);
     $panel->setTable($table);
     $tokens = array();
     if ($project_handle) {
         $tokens = array($project_handle);
     }
     $filter = $this->renderReportFilters($tokens, $has_window = true);
     return array($filter, $panel);
 }