/**
  * Create a HeraldAction to save from data.
  *
  * $data is of the form:
  *   array(
  *     0 => <action type>
  *     1 => array(<targets>)
  *   )
  */
 public static function willSaveAction($rule_type, $author_phid, $data)
 {
     $obj = new HeraldAction();
     $obj->setAction($data[0]);
     // for personal rule types, set the target to be the owner of the rule
     if ($rule_type == HeraldRuleTypeConfig::RULE_TYPE_PERSONAL) {
         switch ($obj->getAction()) {
             case HeraldActionConfig::ACTION_EMAIL:
             case HeraldActionConfig::ACTION_ADD_CC:
             case HeraldActionConfig::ACTION_REMOVE_CC:
             case HeraldActionConfig::ACTION_AUDIT:
                 $data[1] = array($author_phid => $author_phid);
                 break;
             case HeraldActionConfig::ACTION_FLAG:
                 // Make sure flag color is valid; set to blue if not.
                 $color_map = PhabricatorFlagColor::getColorNameMap();
                 if (empty($color_map[$data[1]])) {
                     $data[1] = PhabricatorFlagColor::COLOR_BLUE;
                 }
                 break;
             case HeraldActionConfig::ACTION_NOTHING:
                 break;
             default:
                 throw new Exception('Unrecognized action type: ' . $obj->getAction());
         }
     }
     if (is_array($data[1])) {
         $obj->setTarget(array_keys($data[1]));
     } else {
         $obj->setTarget($data[1]);
     }
     return $obj;
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $query = new PhabricatorFlagQuery();
     $owner_phids = $request->getValue('ownerPHIDs', array());
     if ($owner_phids) {
         $query->withOwnerPHIDs($owner_phids);
     }
     $object_phids = $request->getValue('objectPHIDs', array());
     if ($object_phids) {
         $query->withObjectPHIDs($object_phids);
     }
     $types = $request->getValue('types', array());
     if ($types) {
         $query->withTypes($types);
     }
     $query->needHandles(true);
     $query->setOffset($request->getValue('offset', 0));
     $query->setLimit($request->getValue('limit', 100));
     $flags = $query->execute();
     $results = array();
     foreach ($flags as $flag) {
         $color = $flag->getColor();
         $uri = PhabricatorEnv::getProductionURI($flag->getHandle()->getURI());
         $results[] = array('id' => $flag->getID(), 'ownerPHID' => $flag->getOwnerPHID(), 'type' => $flag->getType(), 'objectPHID' => $flag->getObjectPHID(), 'reasonPHID' => $flag->getReasonPHID(), 'color' => $color, 'colorName' => PhabricatorFlagColor::getColorName($color), 'note' => $flag->getNote(), 'handle' => array('uri' => $uri, 'name' => $flag->getHandle()->getName()), 'dateCreated' => $flag->getDateCreated(), 'dateModified' => $flag->getDateModified());
     }
     return $results;
 }
 private function handleActionEvent($event)
 {
     $user = $event->getUser();
     $object = $event->getValue('object');
     if (!$object || !$object->getPHID()) {
         // If we have no object, or the object doesn't have a PHID yet, we can't
         // flag it.
         return;
     }
     if (!$object instanceof PhabricatorFlaggableInterface) {
         return;
     }
     if (!$this->canUseApplication($event->getUser())) {
         return null;
     }
     $flag = PhabricatorFlagQuery::loadUserFlag($user, $object->getPHID());
     if ($flag) {
         $color = PhabricatorFlagColor::getColorName($flag->getColor());
         $flag_icon = PhabricatorFlagColor::getIcon($flag->getColor());
         $flag_action = id(new PhabricatorActionView())->setWorkflow(true)->setHref('/flag/delete/' . $flag->getID() . '/')->setName(pht('Remove %s Flag', $color))->setIcon($flag_icon);
     } else {
         $flag_action = id(new PhabricatorActionView())->setWorkflow(true)->setHref('/flag/edit/' . $object->getPHID() . '/')->setName(pht('Flag For Later'))->setIcon('fa-flag');
         if (!$user->isLoggedIn()) {
             $flag_action->setDisabled(true);
         }
     }
     $actions = $event->getValue('actions');
     $actions[] = $flag_action;
     $event->setValue('actions', $actions);
 }
 protected function renderActionEffectDescription($type, $data)
 {
     switch ($type) {
         case self::DO_IGNORE:
             return pht('Already marked with %s flag.', PhabricatorFlagColor::getColorName($data));
         case self::DO_FLAG:
             return pht('Marked with "%s" flag.', PhabricatorFlagColor::getColorName($data));
     }
 }
 public function render()
 {
     $user = $this->user;
     require_celerity_resource('phabricator-flag-css');
     $rows = array();
     foreach ($this->flags as $flag) {
         $class = PhabricatorFlagColor::getCSSClass($flag->getColor());
         $rows[] = array(phutil_render_tag('div', array('class' => 'phabricator-flag-icon ' . $class), ''), $flag->getHandle()->renderLink(), phutil_escape_html($flag->getNote()), phabricator_datetime($flag->getDateCreated(), $user), phabricator_render_form($user, array('method' => 'POST', 'action' => '/flag/edit/' . $flag->getObjectPHID() . '/', 'sigil' => 'workflow'), phutil_render_tag('button', array('class' => 'small grey'), 'Edit Flag')), phabricator_render_form($user, array('method' => 'POST', 'action' => '/flag/delete/' . $flag->getID() . '/', 'sigil' => 'workflow'), phutil_render_tag('button', array('class' => 'small grey'), 'Remove Flag')));
     }
     $table = new AphrontTableView($rows);
     $table->setHeaders(array('', 'Flagged Object', 'Note', 'Flagged On', '', ''));
     $table->setColumnClasses(array('', 'pri', 'wide', '', 'action', 'action'));
     $table->setNoDataString('No flags.');
     return $table->render();
 }
 private function handleActionEvent($event)
 {
     $user = $event->getUser();
     $object = $event->getValue('object');
     $flag = PhabricatorFlagQuery::loadUserFlag($user, $object->getPHID());
     if ($flag) {
         $color = PhabricatorFlagColor::getColorName($flag->getColor());
         $flag_action = id(new PhabricatorActionView())->setWorkflow(true)->setHref('/flag/delete/' . $flag->getID() . '/')->setName(phutil_escape_html('Remove ' . $color . ' Flag'))->setIcon('flag-' . $flag->getColor());
     } else {
         $flag_action = id(new PhabricatorActionView())->setWorkflow(true)->setHref('/flag/edit/' . $object->getPHID() . '/')->setName('Flag For Later')->setIcon('flag-ghost');
         if (!$user->isLoggedIn()) {
             $flag_action->setDisabled(true);
         }
     }
     $actions = $event->getValue('actions');
     $actions[] = $flag_action;
     $event->setValue('actions', $actions);
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $phid = $this->phid;
     $handle = PhabricatorObjectHandleData::loadOneHandle($phid);
     if (!$handle->isComplete()) {
         return new Aphront404Response();
     }
     $flag = PhabricatorFlagQuery::loadUserFlag($user, $phid);
     if (!$flag) {
         $flag = new PhabricatorFlag();
         $flag->setOwnerPHID($user->getPHID());
         $flag->setType($handle->getType());
         $flag->setObjectPHID($handle->getPHID());
         $flag->setReasonPHID($user->getPHID());
     }
     if ($request->isDialogFormPost()) {
         $flag->setColor($request->getInt('color'));
         $flag->setNote($request->getStr('note'));
         $flag->save();
         return id(new AphrontReloadResponse())->setURI('/flag/');
     }
     $type_name = $handle->getTypeName();
     $dialog = new AphrontDialogView();
     $dialog->setUser($user);
     $dialog->setTitle("Flag {$type_name}");
     require_celerity_resource('phabricator-flag-css');
     $form = new AphrontFormLayoutView();
     $is_new = !$flag->getID();
     if ($is_new) {
         $form->appendChild("<p>You can flag this {$type_name} if you want to remember to look " . "at it later.</p><br />");
     }
     $radio = new AphrontFormRadioButtonControl();
     foreach (PhabricatorFlagColor::getColorNameMap() as $color => $text) {
         $class = 'phabricator-flag-radio phabricator-flag-color-' . $color;
         $radio->addButton($color, $text, '', $class);
     }
     $form->appendChild($radio->setName('color')->setLabel('Flag Color')->setValue($flag->getColor()))->appendChild(id(new AphrontFormTextAreaControl())->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_SHORT)->setName('note')->setLabel('Note')->setValue($flag->getNote()));
     $dialog->appendChild($form);
     $dialog->addCancelButton($handle->getURI());
     $dialog->addSubmitButton($is_new ? "Flag {$type_name}" : 'Save');
     return id(new AphrontDialogResponse())->setDialog($dialog);
 }
 protected function renderInput()
 {
     require_celerity_resource('phabricator-flag-css');
     $colors = PhabricatorFlagColor::getColorNameMap();
     $value_map = array_fuse($this->getValue());
     $file_map = array(PhabricatorFlagColor::COLOR_RED => 'red', PhabricatorFlagColor::COLOR_ORANGE => 'orange', PhabricatorFlagColor::COLOR_YELLOW => 'yellow', PhabricatorFlagColor::COLOR_GREEN => 'green', PhabricatorFlagColor::COLOR_BLUE => 'blue', PhabricatorFlagColor::COLOR_PINK => 'pink', PhabricatorFlagColor::COLOR_PURPLE => 'purple', PhabricatorFlagColor::COLOR_CHECKERED => 'finish');
     $out = array();
     foreach ($colors as $const => $name) {
         // TODO: This should probably be a sprite sheet.
         $partial = $file_map[$const];
         $uri = '/rsrc/image/icon/fatcow/flag_' . $partial . '.png';
         $uri = celerity_get_resource_uri($uri);
         $icon = id(new PHUIIconView())->setImage($uri);
         $input = phutil_tag('input', array('type' => 'checkbox', 'name' => $this->getName() . '[]', 'value' => $const, 'checked' => isset($value_map[$const]) ? 'checked' : null, 'class' => 'phabricator-flag-select-checkbox'));
         $label = phutil_tag('label', array('class' => 'phabricator-flag-select-label'), array($icon, $input));
         $out[] = $label;
     }
     return $out;
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $phid = $request->getURIData('phid');
     $handle = id(new PhabricatorHandleQuery())->setViewer($viewer)->withPHIDs(array($phid))->executeOne();
     if (!$handle->isComplete()) {
         return new Aphront404Response();
     }
     $flag = PhabricatorFlagQuery::loadUserFlag($viewer, $phid);
     if (!$flag) {
         $flag = new PhabricatorFlag();
         $flag->setOwnerPHID($viewer->getPHID());
         $flag->setType($handle->getType());
         $flag->setObjectPHID($handle->getPHID());
         $flag->setReasonPHID($viewer->getPHID());
     }
     if ($request->isDialogFormPost()) {
         $flag->setColor($request->getInt('color'));
         $flag->setNote($request->getStr('note'));
         $flag->save();
         return id(new AphrontReloadResponse())->setURI('/flag/');
     }
     $type_name = $handle->getTypeName();
     $dialog = new AphrontDialogView();
     $dialog->setUser($viewer);
     $dialog->setTitle(pht('Flag %s', $type_name));
     require_celerity_resource('phabricator-flag-css');
     $form = new PHUIFormLayoutView();
     $is_new = !$flag->getID();
     if ($is_new) {
         $form->appendChild(hsprintf('<p>%s</p><br />', pht('You can flag this %s if you want to remember to look ' . 'at it later.', $type_name)));
     }
     $radio = new AphrontFormRadioButtonControl();
     foreach (PhabricatorFlagColor::getColorNameMap() as $color => $text) {
         $class = 'phabricator-flag-radio phabricator-flag-color-' . $color;
         $radio->addButton($color, $text, '', $class);
     }
     $form->appendChild($radio->setName('color')->setLabel(pht('Flag Color'))->setValue($flag->getColor()))->appendChild(id(new AphrontFormTextAreaControl())->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_SHORT)->setName('note')->setLabel(pht('Note'))->setValue($flag->getNote()));
     $dialog->appendChild($form);
     $dialog->addCancelButton($handle->getURI());
     $dialog->addSubmitButton($is_new ? pht('Create Flag') : pht('Save'));
     return id(new AphrontDialogResponse())->setDialog($dialog);
 }
 public function render()
 {
     $user = $this->user;
     if (!$user) {
         throw new Exception("Call setUser() before render()!");
     }
     $flags = id(new PhabricatorFlagQuery())->withOwnerPHIDs(array($user->getPHID()))->withObjectPHIDs(mpull($this->revisions, 'getPHID'))->execute();
     $flagged = mpull($flags, null, 'getObjectPHID');
     foreach ($this->fields as $field) {
         $field->setUser($this->user);
         $field->setHandles($this->handles);
     }
     $rows = array();
     foreach ($this->revisions as $revision) {
         $phid = $revision->getPHID();
         $flag = '';
         if (isset($flagged[$phid])) {
             $class = PhabricatorFlagColor::getCSSClass($flagged[$phid]->getColor());
             $note = $flagged[$phid]->getNote();
             $flag = phutil_render_tag('div', array('class' => 'phabricator-flag-icon ' . $class, 'title' => $note), '');
         }
         $row = array($flag);
         foreach ($this->fields as $field) {
             $row[] = $field->renderValueForRevisionList($revision);
         }
         $rows[] = $row;
     }
     $headers = array('');
     $classes = array('');
     foreach ($this->fields as $field) {
         $headers[] = $field->renderHeaderForRevisionList();
         $classes[] = $field->getColumnClassForRevisionList();
     }
     $table = new AphrontTableView($rows);
     $table->setHeaders($headers);
     $table->setColumnClasses($classes);
     $table->setNoDataString(DifferentialRevisionListView::NO_DATA_STRING);
     return $table->render();
 }
 private function renderHeadsupActionList(PhabricatorRepositoryCommit $commit)
 {
     $user = $this->getRequest()->getUser();
     $actions = array();
     require_celerity_resource('phabricator-flag-css');
     $flag = PhabricatorFlagQuery::loadUserFlag($user, $commit->getPHID());
     if ($flag) {
         $class = PhabricatorFlagColor::getCSSClass($flag->getColor());
         $color = PhabricatorFlagColor::getColorName($flag->getColor());
         $action = new AphrontHeadsupActionView();
         $action->setClass('flag-clear ' . $class);
         $action->setURI('/flag/delete/' . $flag->getID() . '/');
         $action->setName('Remove ' . $color . ' Flag');
         $action->setWorkflow(true);
         $actions[] = $action;
     } else {
         $action = new AphrontHeadsupActionView();
         $action->setClass('phabricator-flag-ghost');
         $action->setURI('/flag/edit/' . $commit->getPHID() . '/');
         $action->setName('Flag Commit');
         $action->setWorkflow(true);
         $actions[] = $action;
     }
     require_celerity_resource('phabricator-object-selector-css');
     require_celerity_resource('javelin-behavior-phabricator-object-selector');
     $action = new AphrontHeadsupActionView();
     $action->setName('Edit Maniphest Tasks');
     $action->setURI('/search/attach/' . $commit->getPHID() . '/TASK/edge/');
     $action->setWorkflow(true);
     $action->setClass('attach-maniphest');
     $actions[] = $action;
     if ($user->getIsAdmin()) {
         $action = new AphrontHeadsupActionView();
         $action->setName('MetaMTA Transcripts');
         $action->setURI('/mail/?phid=' . $commit->getPHID());
         $action->setClass('transcripts-metamta');
         $actions[] = $action;
     }
     $action = new AphrontHeadsupActionView();
     $action->setName('Herald Transcripts');
     $action->setURI('/herald/transcript/?phid=' . $commit->getPHID());
     $action->setClass('transcripts-herald');
     $actions[] = $action;
     $action_list = new AphrontHeadsupActionListView();
     $action_list->setActions($actions);
     return $action_list;
 }
 protected function renderResultList(array $flags, PhabricatorSavedQuery $query, array $handles)
 {
     assert_instances_of($flags, 'PhabricatorFlag');
     $viewer = $this->requireViewer();
     $list = id(new PHUIObjectItemListView())->setUser($viewer);
     foreach ($flags as $flag) {
         $id = $flag->getID();
         $phid = $flag->getObjectPHID();
         $class = PhabricatorFlagColor::getCSSClass($flag->getColor());
         $flag_icon = phutil_tag('div', array('class' => 'phabricator-flag-icon ' . $class), '');
         $item = id(new PHUIObjectItemView())->addHeadIcon($flag_icon)->setHeader($flag->getHandle()->renderLink());
         $item->addAction(id(new PHUIListItemView())->setIcon('fa-pencil')->setHref($this->getApplicationURI("edit/{$phid}/"))->setWorkflow(true));
         $item->addAction(id(new PHUIListItemView())->setIcon('fa-times')->setHref($this->getApplicationURI("delete/{$id}/"))->setWorkflow(true));
         if ($flag->getNote()) {
             $item->addAttribute($flag->getNote());
         }
         $item->addIcon('none', phabricator_datetime($flag->getDateCreated(), $viewer));
         $list->addItem($item);
     }
     return $list;
 }
 protected function buildFlagInfoDictionary($flag)
 {
     $color = $flag->getColor();
     $uri = PhabricatorEnv::getProductionURI($flag->getHandle()->getURI());
     return array('id' => $flag->getID(), 'ownerPHID' => $flag->getOwnerPHID(), 'type' => $flag->getType(), 'objectPHID' => $flag->getObjectPHID(), 'reasonPHID' => $flag->getReasonPHID(), 'color' => $color, 'colorName' => PhabricatorFlagColor::getColorName($color), 'note' => $flag->getNote(), 'handle' => array('uri' => $uri, 'name' => $flag->getHandle()->getName(), 'fullname' => $flag->getHandle()->getFullName()), 'dateCreated' => $flag->getDateCreated(), 'dateModified' => $flag->getDateModified());
 }
 private function getRevisionActions(DifferentialRevision $revision)
 {
     $user = $this->getRequest()->getUser();
     $viewer_phid = $user->getPHID();
     $viewer_is_owner = $revision->getAuthorPHID() == $viewer_phid;
     $viewer_is_reviewer = in_array($viewer_phid, $revision->getReviewers());
     $viewer_is_cc = in_array($viewer_phid, $revision->getCCPHIDs());
     $viewer_is_anonymous = !$this->getRequest()->getUser()->isLoggedIn();
     $status = $revision->getStatus();
     $revision_id = $revision->getID();
     $revision_phid = $revision->getPHID();
     $links = array();
     if ($viewer_is_owner) {
         $links[] = array('class' => 'revision-edit', 'href' => "/differential/revision/edit/{$revision_id}/", 'name' => 'Edit Revision');
     }
     if (!$viewer_is_anonymous) {
         require_celerity_resource('phabricator-flag-css');
         $flag = PhabricatorFlagQuery::loadUserFlag($user, $revision_phid);
         if ($flag) {
             $class = PhabricatorFlagColor::getCSSClass($flag->getColor());
             $color = PhabricatorFlagColor::getColorName($flag->getColor());
             $links[] = array('class' => 'flag-clear ' . $class, 'href' => '/flag/delete/' . $flag->getID() . '/', 'name' => phutil_escape_html('Remove ' . $color . ' Flag'), 'sigil' => 'workflow');
         } else {
             $links[] = array('class' => 'flag-add phabricator-flag-ghost', 'href' => '/flag/edit/' . $revision_phid . '/', 'name' => 'Flag Revision', 'sigil' => 'workflow');
         }
         if (!$viewer_is_owner && !$viewer_is_reviewer) {
             $action = $viewer_is_cc ? 'rem' : 'add';
             $links[] = array('class' => $viewer_is_cc ? 'subscribe-rem' : 'subscribe-add', 'href' => "/differential/subscribe/{$action}/{$revision_id}/", 'name' => $viewer_is_cc ? 'Unsubscribe' : 'Subscribe', 'instant' => true);
         } else {
             $links[] = array('class' => 'subscribe-rem unavailable', 'name' => 'Automatically Subscribed');
         }
         require_celerity_resource('phabricator-object-selector-css');
         require_celerity_resource('javelin-behavior-phabricator-object-selector');
         $links[] = array('class' => 'action-dependencies', 'name' => 'Edit Dependencies', 'href' => "/search/attach/{$revision_phid}/DREV/dependencies/", 'sigil' => 'workflow');
         if (PhabricatorEnv::getEnvConfig('maniphest.enabled')) {
             $links[] = array('class' => 'attach-maniphest', 'name' => 'Edit Maniphest Tasks', 'href' => "/search/attach/{$revision_phid}/TASK/", 'sigil' => 'workflow');
         }
         if ($user->getIsAdmin()) {
             $links[] = array('class' => 'transcripts-metamta', 'name' => 'MetaMTA Transcripts', 'href' => "/mail/?phid={$revision_phid}");
         }
         $links[] = array('class' => 'transcripts-herald', 'name' => 'Herald Transcripts', 'href' => "/herald/transcript/?phid={$revision_phid}");
     }
     $request_uri = $this->getRequest()->getRequestURI();
     $links[] = array('class' => 'action-download', 'name' => 'Download Raw Diff', 'href' => $request_uri->alter('download', 'true'));
     return $links;
 }
 private function buildApplyTranscriptPanel(HeraldTranscript $xscript)
 {
     $handles = $this->handles;
     $adapter = $this->getAdapter();
     $rule_type_global = HeraldRuleTypeConfig::RULE_TYPE_GLOBAL;
     $action_names = $adapter->getActionNameMap($rule_type_global);
     $list = new PHUIObjectItemListView();
     $list->setStates(true);
     $list->setNoDataString(pht('No actions were taken.'));
     foreach ($xscript->getApplyTranscripts() as $apply_xscript) {
         $target = $apply_xscript->getTarget();
         switch ($apply_xscript->getAction()) {
             case HeraldAdapter::ACTION_NOTHING:
                 $target = null;
                 break;
             case HeraldAdapter::ACTION_FLAG:
                 $target = PhabricatorFlagColor::getColorName($target);
                 break;
             case HeraldAdapter::ACTION_BLOCK:
                 // Target is a text string.
                 $target = $target;
                 break;
             default:
                 if (is_array($target) && $target) {
                     foreach ($target as $k => $phid) {
                         if (isset($handles[$phid])) {
                             $target[$k] = $handles[$phid]->getName();
                         }
                     }
                     $target = implode(', ', $target);
                 } else {
                     if (is_string($target)) {
                         $target = $target;
                     } else {
                         $target = '<empty>';
                     }
                 }
                 break;
         }
         $item = new PHUIObjectItemView();
         if ($apply_xscript->getApplied()) {
             $item->setState(PHUIObjectItemView::STATE_SUCCESS);
         } else {
             $item->setState(PHUIObjectItemView::STATE_FAIL);
         }
         $rule = idx($action_names, $apply_xscript->getAction(), pht('Unknown Action "%s"', $apply_xscript->getAction()));
         $item->setHeader(pht('%s: %s', $rule, $target));
         $item->addAttribute($apply_xscript->getReason());
         $item->addAttribute(pht('Outcome: %s', $apply_xscript->getAppliedReason()));
         $list->addItem($item);
     }
     $box = new PHUIObjectBoxView();
     $box->setHeaderText(pht('Actions Taken'));
     $box->appendChild($list);
     return $box;
 }
 private function renderActionTargetAsText(HeraldAction $action, PhabricatorHandleList $handles)
 {
     $target = $action->getTarget();
     if (!is_array($target)) {
         $target = array($target);
     }
     foreach ($target as $index => $val) {
         switch ($action->getAction()) {
             case self::ACTION_FLAG:
                 $target[$index] = PhabricatorFlagColor::getColorName($val);
                 break;
             default:
                 $handle = $handles->getHandleIfExists($val);
                 if ($handle) {
                     $target[$index] = $handle->renderLink();
                 }
                 break;
         }
     }
     $target = phutil_implode_html(', ', $target);
     return $target;
 }
 protected function renderResultList(array $flags, PhabricatorSavedQuery $query, array $handles)
 {
     assert_instances_of($flags, 'PhabricatorFlag');
     $viewer = $this->requireViewer();
     $list = id(new PHUIObjectItemListView())->setUser($viewer);
     foreach ($flags as $flag) {
         $id = $flag->getID();
         $phid = $flag->getObjectPHID();
         $class = PhabricatorFlagColor::getCSSClass($flag->getColor());
         $flag_icon = phutil_tag('div', array('class' => 'phabricator-flag-icon ' . $class), '');
         $item = id(new PHUIObjectItemView())->addHeadIcon($flag_icon)->setHeader($flag->getHandle()->getFullName())->setHref($flag->getHandle()->getURI());
         $status_open = PhabricatorObjectHandle::STATUS_OPEN;
         if ($flag->getHandle()->getStatus() != $status_open) {
             $item->setDisabled(true);
         }
         $item->addAction(id(new PHUIListItemView())->setIcon('fa-pencil')->setHref($this->getApplicationURI("edit/{$phid}/"))->setWorkflow(true));
         $item->addAction(id(new PHUIListItemView())->setIcon('fa-times')->setHref($this->getApplicationURI("delete/{$id}/"))->setWorkflow(true));
         if ($flag->getNote()) {
             $item->addAttribute($flag->getNote());
         }
         $item->addIcon('none', phabricator_datetime($flag->getDateCreated(), $viewer));
         $list->addItem($item);
     }
     $result = new PhabricatorApplicationSearchResultView();
     $result->setObjectList($list);
     $result->setNoDataString(pht('No flags found.'));
     return $result;
 }
 private function renderHeadsupActionList(PhabricatorRepositoryCommit $commit, PhabricatorRepository $repository)
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $actions = array();
     // TODO -- integrate permissions into whether or not this action is shown
     $uri = '/diffusion/' . $repository->getCallSign() . '/commit/' . $commit->getCommitIdentifier() . '/edit/';
     $action = new AphrontHeadsupActionView();
     $action->setClass('action-edit');
     $action->setURI($uri);
     $action->setName('Edit Commit');
     $action->setWorkflow(false);
     $actions[] = $action;
     require_celerity_resource('phabricator-flag-css');
     $flag = PhabricatorFlagQuery::loadUserFlag($user, $commit->getPHID());
     if ($flag) {
         $class = PhabricatorFlagColor::getCSSClass($flag->getColor());
         $color = PhabricatorFlagColor::getColorName($flag->getColor());
         $action = new AphrontHeadsupActionView();
         $action->setClass('flag-clear ' . $class);
         $action->setURI('/flag/delete/' . $flag->getID() . '/');
         $action->setName('Remove ' . $color . ' Flag');
         $action->setWorkflow(true);
         $actions[] = $action;
     } else {
         $action = new AphrontHeadsupActionView();
         $action->setClass('phabricator-flag-ghost');
         $action->setURI('/flag/edit/' . $commit->getPHID() . '/');
         $action->setName('Flag Commit');
         $action->setWorkflow(true);
         $actions[] = $action;
     }
     require_celerity_resource('phabricator-object-selector-css');
     require_celerity_resource('javelin-behavior-phabricator-object-selector');
     $action = new AphrontHeadsupActionView();
     $action->setName('Edit Maniphest Tasks');
     $action->setURI('/search/attach/' . $commit->getPHID() . '/TASK/edge/');
     $action->setWorkflow(true);
     $action->setClass('attach-maniphest');
     $actions[] = $action;
     if ($user->getIsAdmin()) {
         $action = new AphrontHeadsupActionView();
         $action->setName('MetaMTA Transcripts');
         $action->setURI('/mail/?phid=' . $commit->getPHID());
         $action->setClass('transcripts-metamta');
         $actions[] = $action;
     }
     $action = new AphrontHeadsupActionView();
     $action->setName('Herald Transcripts');
     $action->setURI('/herald/transcript/?phid=' . $commit->getPHID());
     $action->setClass('transcripts-herald');
     $actions[] = $action;
     $action = new AphrontHeadsupActionView();
     $action->setName('Download Raw Diff');
     $action->setURI($request->getRequestURI()->alter('diff', true));
     $action->setClass('action-download');
     $actions[] = $action;
     $action_list = new AphrontHeadsupActionListView();
     $action_list->setActions($actions);
     return $action_list;
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $e_title = null;
     $priority_map = ManiphestTaskPriority::getTaskPriorityMap();
     $task = id(new ManiphestTask())->load($this->id);
     if (!$task) {
         return new Aphront404Response();
     }
     $workflow = $request->getStr('workflow');
     $parent_task = null;
     if ($workflow && is_numeric($workflow)) {
         $parent_task = id(new ManiphestTask())->load($workflow);
     }
     $transactions = id(new ManiphestTransaction())->loadAllWhere('taskID = %d ORDER BY id ASC', $task->getID());
     $e_commit = PhabricatorEdgeConfig::TYPE_TASK_HAS_COMMIT;
     $e_dep_on = PhabricatorEdgeConfig::TYPE_TASK_DEPENDS_ON_TASK;
     $e_dep_by = PhabricatorEdgeConfig::TYPE_TASK_DEPENDED_ON_BY_TASK;
     $e_rev = PhabricatorEdgeConfig::TYPE_TASK_HAS_RELATED_DREV;
     $phid = $task->getPHID();
     $query = id(new PhabricatorEdgeQuery())->withSourcePHIDs(array($phid))->withEdgeTypes(array($e_commit, $e_dep_on, $e_dep_by, $e_rev));
     $edges = $query->execute();
     $commit_phids = array_keys($edges[$phid][$e_commit]);
     $dep_on_tasks = array_keys($edges[$phid][$e_dep_on]);
     $dep_by_tasks = array_keys($edges[$phid][$e_dep_by]);
     $revs = array_keys($edges[$phid][$e_rev]);
     $phids = array_fill_keys($query->getDestinationPHIDs(), true);
     foreach ($transactions as $transaction) {
         foreach ($transaction->extractPHIDs() as $phid) {
             $phids[$phid] = true;
         }
     }
     foreach ($task->getCCPHIDs() as $phid) {
         $phids[$phid] = true;
     }
     foreach ($task->getProjectPHIDs() as $phid) {
         $phids[$phid] = true;
     }
     if ($task->getOwnerPHID()) {
         $phids[$task->getOwnerPHID()] = true;
     }
     $phids[$task->getAuthorPHID()] = true;
     $attached = $task->getAttached();
     foreach ($attached as $type => $list) {
         foreach ($list as $phid => $info) {
             $phids[$phid] = true;
         }
     }
     if ($parent_task) {
         $phids[$parent_task->getPHID()] = true;
     }
     $phids = array_keys($phids);
     $handles = $this->loadViewerHandles($phids);
     $dict = array();
     $dict['Status'] = '<strong>' . ManiphestTaskStatus::getTaskStatusFullName($task->getStatus()) . '</strong>';
     $dict['Assigned To'] = $task->getOwnerPHID() ? $handles[$task->getOwnerPHID()]->renderLink() : '<em>None</em>';
     $dict['Priority'] = ManiphestTaskPriority::getTaskPriorityName($task->getPriority());
     $cc = $task->getCCPHIDs();
     if ($cc) {
         $cc_links = array();
         foreach ($cc as $phid) {
             $cc_links[] = $handles[$phid]->renderLink();
         }
         $dict['CC'] = implode(', ', $cc_links);
     } else {
         $dict['CC'] = '<em>None</em>';
     }
     $dict['Author'] = $handles[$task->getAuthorPHID()]->renderLink();
     $source = $task->getOriginalEmailSource();
     if ($source) {
         $subject = '[T' . $task->getID() . '] ' . $task->getTitle();
         $dict['From Email'] = phutil_render_tag('a', array('href' => 'mailto:' . $source . '?subject=' . $subject), phutil_escape_html($source));
     }
     $projects = $task->getProjectPHIDs();
     if ($projects) {
         $project_links = array();
         foreach ($projects as $phid) {
             $project_links[] = $handles[$phid]->renderLink();
         }
         $dict['Projects'] = implode(', ', $project_links);
     } else {
         $dict['Projects'] = '<em>None</em>';
     }
     $extensions = ManiphestTaskExtensions::newExtensions();
     $aux_fields = $extensions->getAuxiliaryFieldSpecifications();
     if ($aux_fields) {
         $task->loadAndAttachAuxiliaryAttributes();
         foreach ($aux_fields as $aux_field) {
             $aux_key = $aux_field->getAuxiliaryKey();
             $aux_field->setValue($task->getAuxiliaryAttribute($aux_key));
             $value = $aux_field->renderForDetailView();
             if (strlen($value)) {
                 $dict[$aux_field->getLabel()] = $value;
             }
         }
     }
     if ($dep_by_tasks) {
         $dict['Dependent Tasks'] = $this->renderHandleList(array_select_keys($handles, $dep_by_tasks));
     }
     if ($dep_on_tasks) {
         $dict['Depends On'] = $this->renderHandleList(array_select_keys($handles, $dep_on_tasks));
     }
     if ($revs) {
         $dict['Revisions'] = $this->renderHandleList(array_select_keys($handles, $revs));
     }
     if ($commit_phids) {
         $dict['Commits'] = $this->renderHandleList(array_select_keys($handles, $commit_phids));
     }
     $file_infos = idx($attached, PhabricatorPHIDConstants::PHID_TYPE_FILE);
     if ($file_infos) {
         $file_phids = array_keys($file_infos);
         $files = id(new PhabricatorFile())->loadAllWhere('phid IN (%Ls)', $file_phids);
         $views = array();
         foreach ($files as $file) {
             $view = new AphrontFilePreviewView();
             $view->setFile($file);
             $views[] = $view->render();
         }
         $dict['Files'] = implode('', $views);
     }
     $context_bar = null;
     if ($parent_task) {
         $context_bar = new AphrontContextBarView();
         $context_bar->addButton(phutil_render_tag('a', array('href' => '/maniphest/task/create/?parent=' . $parent_task->getID(), 'class' => 'green button'), 'Create Another Subtask'));
         $context_bar->appendChild('Created a subtask of <strong>' . $handles[$parent_task->getPHID()]->renderLink() . '</strong>');
     } else {
         if ($workflow == 'create') {
             $context_bar = new AphrontContextBarView();
             $context_bar->addButton('<label>Create Another:</label>');
             $context_bar->addButton(phutil_render_tag('a', array('href' => '/maniphest/task/create/?template=' . $task->getID(), 'class' => 'green button'), 'Similar Task'));
             $context_bar->addButton(phutil_render_tag('a', array('href' => '/maniphest/task/create/', 'class' => 'green button'), 'Empty Task'));
             $context_bar->appendChild('New task created.');
         }
     }
     $actions = array();
     $action = new AphrontHeadsupActionView();
     $action->setName('Edit Task');
     $action->setURI('/maniphest/task/edit/' . $task->getID() . '/');
     $action->setClass('action-edit');
     $actions[] = $action;
     require_celerity_resource('phabricator-flag-css');
     $flag = PhabricatorFlagQuery::loadUserFlag($user, $task->getPHID());
     if ($flag) {
         $class = PhabricatorFlagColor::getCSSClass($flag->getColor());
         $color = PhabricatorFlagColor::getColorName($flag->getColor());
         $action = new AphrontHeadsupActionView();
         $action->setClass('flag-clear ' . $class);
         $action->setURI('/flag/delete/' . $flag->getID() . '/');
         $action->setName('Remove ' . $color . ' Flag');
         $action->setWorkflow(true);
         $actions[] = $action;
     } else {
         $action = new AphrontHeadsupActionView();
         $action->setClass('phabricator-flag-ghost');
         $action->setURI('/flag/edit/' . $task->getPHID() . '/');
         $action->setName('Flag Task');
         $action->setWorkflow(true);
         $actions[] = $action;
     }
     require_celerity_resource('phabricator-object-selector-css');
     require_celerity_resource('javelin-behavior-phabricator-object-selector');
     $action = new AphrontHeadsupActionView();
     $action->setName('Merge Duplicates');
     $action->setURI('/search/attach/' . $task->getPHID() . '/TASK/merge/');
     $action->setWorkflow(true);
     $action->setClass('action-merge');
     $actions[] = $action;
     $action = new AphrontHeadsupActionView();
     $action->setName('Create Subtask');
     $action->setURI('/maniphest/task/create/?parent=' . $task->getID());
     $action->setClass('action-branch');
     $actions[] = $action;
     $action = new AphrontHeadsupActionView();
     $action->setName('Edit Dependencies');
     $action->setURI('/search/attach/' . $task->getPHID() . '/TASK/dependencies/');
     $action->setWorkflow(true);
     $action->setClass('action-dependencies');
     $actions[] = $action;
     $action = new AphrontHeadsupActionView();
     $action->setName('Edit Differential Revisions');
     $action->setURI('/search/attach/' . $task->getPHID() . '/DREV/');
     $action->setWorkflow(true);
     $action->setClass('action-attach');
     $actions[] = $action;
     $action_list = new AphrontHeadsupActionListView();
     $action_list->setActions($actions);
     $headsup_panel = new AphrontHeadsupView();
     $headsup_panel->setObjectName('T' . $task->getID());
     $headsup_panel->setHeader($task->getTitle());
     $headsup_panel->setActionList($action_list);
     $headsup_panel->setProperties($dict);
     $engine = new PhabricatorMarkupEngine();
     $engine->setViewer($user);
     $engine->addObject($task, ManiphestTask::MARKUP_FIELD_DESCRIPTION);
     foreach ($transactions as $xaction) {
         if ($xaction->hasComments()) {
             $engine->addObject($xaction, ManiphestTransaction::MARKUP_FIELD_BODY);
         }
     }
     $engine->process();
     $headsup_panel->appendChild('<div class="phabricator-remarkup">' . $engine->getOutput($task, ManiphestTask::MARKUP_FIELD_DESCRIPTION) . '</div>');
     $transaction_types = ManiphestTransactionType::getTransactionTypeMap();
     $resolution_types = ManiphestTaskStatus::getTaskStatusMap();
     if ($task->getStatus() == ManiphestTaskStatus::STATUS_OPEN) {
         $resolution_types = array_select_keys($resolution_types, array(ManiphestTaskStatus::STATUS_CLOSED_RESOLVED, ManiphestTaskStatus::STATUS_CLOSED_WONTFIX, ManiphestTaskStatus::STATUS_CLOSED_INVALID, ManiphestTaskStatus::STATUS_CLOSED_SPITE));
     } else {
         $resolution_types = array(ManiphestTaskStatus::STATUS_OPEN => 'Reopened');
         $transaction_types[ManiphestTransactionType::TYPE_STATUS] = 'Reopen Task';
         unset($transaction_types[ManiphestTransactionType::TYPE_PRIORITY]);
         unset($transaction_types[ManiphestTransactionType::TYPE_OWNER]);
     }
     $default_claim = array($user->getPHID() => $user->getUsername() . ' (' . $user->getRealName() . ')');
     $draft = id(new PhabricatorDraft())->loadOneWhere('authorPHID = %s AND draftKey = %s', $user->getPHID(), $task->getPHID());
     if ($draft) {
         $draft_text = $draft->getDraft();
     } else {
         $draft_text = null;
     }
     $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
     if ($is_serious) {
         // Prevent tasks from being closed "out of spite" in serious business
         // installs.
         unset($resolution_types[ManiphestTaskStatus::STATUS_CLOSED_SPITE]);
     }
     $comment_form = new AphrontFormView();
     $comment_form->setUser($user)->setAction('/maniphest/transaction/save/')->setEncType('multipart/form-data')->addHiddenInput('taskID', $task->getID())->appendChild(id(new AphrontFormSelectControl())->setLabel('Action')->setName('action')->setOptions($transaction_types)->setID('transaction-action'))->appendChild(id(new AphrontFormSelectControl())->setLabel('Resolution')->setName('resolution')->setControlID('resolution')->setControlStyle('display: none')->setOptions($resolution_types))->appendChild(id(new AphrontFormTokenizerControl())->setLabel('Assign To')->setName('assign_to')->setControlID('assign_to')->setControlStyle('display: none')->setID('assign-tokenizer')->setDisableBehavior(true))->appendChild(id(new AphrontFormTokenizerControl())->setLabel('CCs')->setName('ccs')->setControlID('ccs')->setControlStyle('display: none')->setID('cc-tokenizer')->setDisableBehavior(true))->appendChild(id(new AphrontFormSelectControl())->setLabel('Priority')->setName('priority')->setOptions($priority_map)->setControlID('priority')->setControlStyle('display: none')->setValue($task->getPriority()))->appendChild(id(new AphrontFormTokenizerControl())->setLabel('Projects')->setName('projects')->setControlID('projects')->setControlStyle('display: none')->setID('projects-tokenizer')->setDisableBehavior(true))->appendChild(id(new AphrontFormFileControl())->setLabel('File')->setName('file')->setControlID('file')->setControlStyle('display: none'))->appendChild(id(new PhabricatorRemarkupControl())->setLabel('Comments')->setName('comments')->setValue($draft_text)->setID('transaction-comments'))->appendChild(id(new AphrontFormDragAndDropUploadControl())->setLabel('Attached Files')->setName('files')->setActivatedClass('aphront-panel-view-drag-and-drop'))->appendChild(id(new AphrontFormSubmitControl())->setValue($is_serious ? 'Submit' : 'Avast!'));
     $control_map = array(ManiphestTransactionType::TYPE_STATUS => 'resolution', ManiphestTransactionType::TYPE_OWNER => 'assign_to', ManiphestTransactionType::TYPE_CCS => 'ccs', ManiphestTransactionType::TYPE_PRIORITY => 'priority', ManiphestTransactionType::TYPE_PROJECTS => 'projects', ManiphestTransactionType::TYPE_ATTACH => 'file');
     $tokenizer_map = array(ManiphestTransactionType::TYPE_PROJECTS => array('id' => 'projects-tokenizer', 'src' => '/typeahead/common/projects/', 'ondemand' => PhabricatorEnv::getEnvConfig('tokenizer.ondemand'), 'placeholder' => 'Type a project name...'), ManiphestTransactionType::TYPE_OWNER => array('id' => 'assign-tokenizer', 'src' => '/typeahead/common/users/', 'value' => $default_claim, 'limit' => 1, 'ondemand' => PhabricatorEnv::getEnvConfig('tokenizer.ondemand'), 'placeholder' => 'Type a user name...'), ManiphestTransactionType::TYPE_CCS => array('id' => 'cc-tokenizer', 'src' => '/typeahead/common/mailable/', 'ondemand' => PhabricatorEnv::getEnvConfig('tokenizer.ondemand'), 'placeholder' => 'Type a user or mailing list...'));
     Javelin::initBehavior('maniphest-transaction-controls', array('select' => 'transaction-action', 'controlMap' => $control_map, 'tokenizers' => $tokenizer_map));
     Javelin::initBehavior('maniphest-transaction-preview', array('uri' => '/maniphest/transaction/preview/' . $task->getID() . '/', 'preview' => 'transaction-preview', 'comments' => 'transaction-comments', 'action' => 'transaction-action', 'map' => $control_map, 'tokenizers' => $tokenizer_map));
     $comment_panel = new AphrontPanelView();
     $comment_panel->appendChild($comment_form);
     $comment_panel->addClass('aphront-panel-accent');
     $comment_panel->setHeader($is_serious ? 'Add Comment' : 'Weigh In');
     $preview_panel = '<div class="aphront-panel-preview">
     <div id="transaction-preview">
       <div class="aphront-panel-preview-loading-text">
         Loading preview...
       </div>
     </div>
   </div>';
     $transaction_view = new ManiphestTransactionListView();
     $transaction_view->setTransactions($transactions);
     $transaction_view->setHandles($handles);
     $transaction_view->setUser($user);
     $transaction_view->setAuxiliaryFields($aux_fields);
     $transaction_view->setMarkupEngine($engine);
     PhabricatorFeedStoryNotification::updateObjectNotificationViews($user, $task->getPHID());
     return $this->buildStandardPageResponse(array($context_bar, $headsup_panel, $transaction_view, $comment_panel, $preview_panel), array('title' => 'T' . $task->getID() . ' ' . $task->getTitle(), 'pageObjects' => array($task->getPHID())));
 }
 public function render()
 {
     $viewer = $this->getViewer();
     $this->initBehavior('phabricator-tooltips', array());
     $this->requireResource('aphront-tooltip-css');
     $list = new PHUIObjectItemListView();
     foreach ($this->revisions as $revision) {
         $item = id(new PHUIObjectItemView())->setUser($viewer);
         $icons = array();
         $phid = $revision->getPHID();
         $flag = $revision->getFlag($viewer);
         if ($flag) {
             $flag_class = PhabricatorFlagColor::getCSSClass($flag->getColor());
             $icons['flag'] = phutil_tag('div', array('class' => 'phabricator-flag-icon ' . $flag_class), '');
         }
         if ($revision->getDrafts($viewer)) {
             $icons['draft'] = true;
         }
         $modified = $revision->getDateModified();
         if (isset($icons['flag'])) {
             $item->addHeadIcon($icons['flag']);
         }
         $item->setObjectName('D' . $revision->getID());
         $item->setHeader($revision->getTitle());
         $item->setHref('/D' . $revision->getID());
         if (isset($icons['draft'])) {
             $draft = id(new PHUIIconView())->setIcon('fa-comment yellow')->addSigil('has-tooltip')->setMetadata(array('tip' => pht('Unsubmitted Comments')));
             $item->addAttribute($draft);
         }
         // Author
         $author_handle = $this->handles[$revision->getAuthorPHID()];
         $item->addByline(pht('Author: %s', $author_handle->renderLink()));
         $unlanded = idx($this->unlandedDependencies, $phid);
         if ($unlanded) {
             $item->addAttribute(array(id(new PHUIIconView())->setIcon('fa-chain-broken', 'red'), ' ', pht('Open Dependencies')));
         }
         $reviewers = array();
         // TODO: As above, this should be based on `getReviewerStatus()`.
         foreach ($revision->getReviewers() as $reviewer) {
             $reviewers[] = $this->handles[$reviewer]->renderLink();
         }
         if (!$reviewers) {
             $reviewers = phutil_tag('em', array(), pht('None'));
         } else {
             $reviewers = phutil_implode_html(', ', $reviewers);
         }
         $item->addAttribute(pht('Reviewers: %s', $reviewers));
         $item->setEpoch($revision->getDateModified());
         if ($revision->isClosed()) {
             $item->setDisabled(true);
         }
         $item->setStatusIcon($revision->getStatusIcon(), $revision->getStatusDisplayName());
         $list->addItem($item);
     }
     $list->setNoDataString($this->noDataString);
     if ($this->header && !$this->noBox) {
         $list->setFlush(true);
         $list = id(new PHUIObjectBoxView())->setBackground($this->background)->setObjectList($list);
         if ($this->header instanceof PHUIHeaderView) {
             $list->setHeader($this->header);
         } else {
             $list->setHeaderText($this->header);
         }
     } else {
         $list->setHeader($this->header);
     }
     return $list;
 }
 public function render()
 {
     $user = $this->user;
     if (!$user) {
         throw new PhutilInvalidStateException('setUser');
     }
     $fresh = PhabricatorEnv::getEnvConfig('differential.days-fresh');
     if ($fresh) {
         $fresh = PhabricatorCalendarHoliday::getNthBusinessDay(time(), -$fresh);
     }
     $stale = PhabricatorEnv::getEnvConfig('differential.days-stale');
     if ($stale) {
         $stale = PhabricatorCalendarHoliday::getNthBusinessDay(time(), -$stale);
     }
     $this->initBehavior('phabricator-tooltips', array());
     $this->requireResource('aphront-tooltip-css');
     $list = new PHUIObjectItemListView();
     foreach ($this->revisions as $revision) {
         $item = id(new PHUIObjectItemView())->setUser($user);
         $icons = array();
         $phid = $revision->getPHID();
         $flag = $revision->getFlag($user);
         if ($flag) {
             $flag_class = PhabricatorFlagColor::getCSSClass($flag->getColor());
             $icons['flag'] = phutil_tag('div', array('class' => 'phabricator-flag-icon ' . $flag_class), '');
         }
         if ($revision->getDrafts($user)) {
             $icons['draft'] = true;
         }
         $modified = $revision->getDateModified();
         $status = $revision->getStatus();
         $show_age = ($fresh || $stale) && $this->highlightAge && !$revision->isClosed();
         if ($stale && $modified < $stale) {
             $object_age = PHUIObjectItemView::AGE_OLD;
         } else {
             if ($fresh && $modified < $fresh) {
                 $object_age = PHUIObjectItemView::AGE_STALE;
             } else {
                 $object_age = PHUIObjectItemView::AGE_FRESH;
             }
         }
         $status_name = ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($status);
         if (isset($icons['flag'])) {
             $item->addHeadIcon($icons['flag']);
         }
         $item->setObjectName('D' . $revision->getID());
         $item->setHeader($revision->getTitle());
         $item->setHref('/D' . $revision->getID());
         if (isset($icons['draft'])) {
             $draft = id(new PHUIIconView())->setIcon('fa-comment yellow')->addSigil('has-tooltip')->setMetadata(array('tip' => pht('Unsubmitted Comments')));
             $item->addAttribute($draft);
         }
         /* Most things 'Need Review', so accept it's the default */
         if ($status != ArcanistDifferentialRevisionStatus::NEEDS_REVIEW) {
             $item->addAttribute($status_name);
         }
         // Author
         $author_handle = $this->handles[$revision->getAuthorPHID()];
         $item->addByline(pht('Author: %s', $author_handle->renderLink()));
         $reviewers = array();
         // TODO: As above, this should be based on `getReviewerStatus()`.
         foreach ($revision->getReviewers() as $reviewer) {
             $reviewers[] = $this->handles[$reviewer]->renderLink();
         }
         if (!$reviewers) {
             $reviewers = phutil_tag('em', array(), pht('None'));
         } else {
             $reviewers = phutil_implode_html(', ', $reviewers);
         }
         $item->addAttribute(pht('Reviewers: %s', $reviewers));
         $item->setEpoch($revision->getDateModified(), $object_age);
         switch ($status) {
             case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW:
                 $item->setStatusIcon('fa-code grey', pht('Needs Review'));
                 break;
             case ArcanistDifferentialRevisionStatus::NEEDS_REVISION:
                 $item->setStatusIcon('fa-refresh red', pht('Needs Revision'));
                 break;
             case ArcanistDifferentialRevisionStatus::CHANGES_PLANNED:
                 $item->setStatusIcon('fa-headphones red', pht('Changes Planned'));
                 break;
             case ArcanistDifferentialRevisionStatus::ACCEPTED:
                 $item->setStatusIcon('fa-check green', pht('Accepted'));
                 break;
             case ArcanistDifferentialRevisionStatus::CLOSED:
                 $item->setDisabled(true);
                 $item->setStatusIcon('fa-check-square-o black', pht('Closed'));
                 break;
             case ArcanistDifferentialRevisionStatus::ABANDONED:
                 $item->setDisabled(true);
                 $item->setStatusIcon('fa-plane black', pht('Abandoned'));
                 break;
         }
         $list->addItem($item);
     }
     $list->setNoDataString($this->noDataString);
     if ($this->header && !$this->noBox) {
         $list->setFlush(true);
         $list = id(new PHUIObjectBoxView())->setObjectList($list);
         if ($this->header instanceof PHUIHeaderView) {
             $list->setHeader($this->header);
         } else {
             $list->setHeaderText($this->header);
         }
     } else {
         $list->setHeader($this->header);
     }
     return $list;
 }
 private function buildApplyTranscriptPanel($xscript)
 {
     $handles = $this->handles;
     $action_names = HeraldActionConfig::getActionMessageMapForRuleType(null);
     $rows = array();
     foreach ($xscript->getApplyTranscripts() as $apply_xscript) {
         $target = $apply_xscript->getTarget();
         switch ($apply_xscript->getAction()) {
             case HeraldActionConfig::ACTION_NOTHING:
                 $target = '';
                 break;
             case HeraldActionConfig::ACTION_FLAG:
                 $target = PhabricatorFlagColor::getColorName($target);
                 break;
             default:
                 if ($target) {
                     foreach ($target as $k => $phid) {
                         $target[$k] = $handles[$phid]->getName();
                     }
                     $target = implode("\n", $target);
                 } else {
                     $target = '<empty>';
                 }
                 break;
         }
         $target = phutil_escape_html($target);
         if ($apply_xscript->getApplied()) {
             $outcome = '<span class="outcome-success">SUCCESS</span>';
         } else {
             $outcome = '<span class="outcome-failure">FAILURE</span>';
         }
         $outcome .= ' ' . phutil_escape_html($apply_xscript->getAppliedReason());
         $rows[] = array(phutil_escape_html($action_names[$apply_xscript->getAction()]), $target, '<strong>Taken because:</strong> ' . phutil_escape_html($apply_xscript->getReason()) . '<br />' . '<strong>Outcome:</strong> ' . $outcome);
     }
     $table = new AphrontTableView($rows);
     $table->setNoDataString('No actions were taken.');
     $table->setHeaders(array('Action', 'Target', 'Details'));
     $table->setColumnClasses(array('', '', 'wide'));
     $panel = new AphrontPanelView();
     $panel->setHeader('Actions Taken');
     $panel->appendChild($table);
     return $panel;
 }
 private function setupEditorBehavior($rule, $handles)
 {
     $serial_conditions = array(array('default', 'default', ''));
     if ($rule->getConditions()) {
         $serial_conditions = array();
         foreach ($rule->getConditions() as $condition) {
             $value = $condition->getValue();
             if (is_array($value)) {
                 $value_map = array();
                 foreach ($value as $k => $fbid) {
                     $value_map[$fbid] = $handles[$fbid]->getName();
                 }
                 $value = $value_map;
             }
             $serial_conditions[] = array($condition->getFieldName(), $condition->getFieldCondition(), $value);
         }
     }
     $serial_actions = array(array('default', ''));
     if ($rule->getActions()) {
         $serial_actions = array();
         foreach ($rule->getActions() as $action) {
             switch ($action->getAction()) {
                 case HeraldActionConfig::ACTION_FLAG:
                     $current_value = $action->getTarget();
                     break;
                 default:
                     $target_map = array();
                     foreach ((array) $action->getTarget() as $fbid) {
                         $target_map[$fbid] = $handles[$fbid]->getName();
                     }
                     $current_value = $target_map;
                     break;
             }
             $serial_actions[] = array($action->getAction(), $current_value);
         }
     }
     $all_rules = $this->loadRulesThisRuleMayDependUpon($rule);
     $all_rules = mpull($all_rules, 'getName', 'getID');
     asort($all_rules);
     $config_info = array();
     $config_info['fields'] = HeraldFieldConfig::getFieldMapForContentType($rule->getContentType());
     $config_info['conditions'] = HeraldConditionConfig::getConditionMap();
     foreach ($config_info['fields'] as $field => $name) {
         $config_info['conditionMap'][$field] = array_keys(HeraldConditionConfig::getConditionMapForField($field));
     }
     foreach ($config_info['fields'] as $field => $fname) {
         foreach ($config_info['conditions'] as $condition => $cname) {
             $config_info['values'][$field][$condition] = HeraldValueTypeConfig::getValueTypeForFieldAndCondition($field, $condition);
         }
     }
     $config_info['actions'] = HeraldActionConfig::getActionMessageMap($rule->getContentType(), $rule->getRuleType());
     $config_info['rule_type'] = $rule->getRuleType();
     foreach ($config_info['actions'] as $action => $name) {
         $config_info['targets'][$action] = HeraldValueTypeConfig::getValueTypeForAction($action, $rule->getRuleType());
     }
     Javelin::initBehavior('herald-rule-editor', array('root' => 'herald-rule-edit-form', 'conditions' => (object) $serial_conditions, 'actions' => (object) $serial_actions, 'template' => $this->buildTokenizerTemplates() + array('rules' => $all_rules, 'colors' => PhabricatorFlagColor::getColorNameMap(), 'defaultColor' => PhabricatorFlagColor::COLOR_BLUE), 'author' => array($rule->getAuthorPHID() => $handles[$rule->getAuthorPHID()]->getName()), 'info' => $config_info));
 }
 private function setupEditorBehavior(HeraldRule $rule, array $handles, HeraldAdapter $adapter)
 {
     $serial_conditions = array(array('default', 'default', ''));
     if ($rule->getConditions()) {
         $serial_conditions = array();
         foreach ($rule->getConditions() as $condition) {
             $value = $adapter->getEditorValueForCondition($this->getViewer(), $condition, $handles);
             $serial_conditions[] = array($condition->getFieldName(), $condition->getFieldCondition(), $value);
         }
     }
     $serial_actions = array(array('default', ''));
     if ($rule->getActions()) {
         $serial_actions = array();
         foreach ($rule->getActions() as $action) {
             switch ($action->getAction()) {
                 case HeraldAdapter::ACTION_FLAG:
                 case HeraldAdapter::ACTION_BLOCK:
                     $current_value = $action->getTarget();
                     break;
                 default:
                     if (is_array($action->getTarget())) {
                         $target_map = array();
                         foreach ((array) $action->getTarget() as $fbid) {
                             $target_map[$fbid] = $handles[$fbid]->getName();
                         }
                         $current_value = $target_map;
                     } else {
                         $current_value = $action->getTarget();
                     }
                     break;
             }
             $serial_actions[] = array($action->getAction(), $current_value);
         }
     }
     $all_rules = $this->loadRulesThisRuleMayDependUpon($rule);
     $all_rules = mpull($all_rules, 'getName', 'getPHID');
     asort($all_rules);
     $all_fields = $adapter->getFieldNameMap();
     $all_conditions = $adapter->getConditionNameMap();
     $all_actions = $adapter->getActionNameMap($rule->getRuleType());
     $fields = $adapter->getFields();
     $field_map = array_select_keys($all_fields, $fields);
     // Populate any fields which exist in the rule but which we don't know the
     // names of, so that saving a rule without touching anything doesn't change
     // it.
     foreach ($rule->getConditions() as $condition) {
         $field_name = $condition->getFieldName();
         if (empty($field_map[$field_name])) {
             $field_map[$field_name] = pht('<Unknown Field "%s">', $field_name);
         }
     }
     $actions = $adapter->getActions($rule->getRuleType());
     $action_map = array_select_keys($all_actions, $actions);
     // Populate any actions which exist in the rule but which we don't know the
     // names of, so that saving a rule without touching anything doesn't change
     // it.
     foreach ($rule->getActions() as $action) {
         $action_name = $action->getAction();
         if (empty($action_map[$action_name])) {
             $action_map[$action_name] = pht('<Unknown Action "%s">', $action_name);
         }
     }
     $config_info = array();
     $config_info['fields'] = $field_map;
     $config_info['conditions'] = $all_conditions;
     $config_info['actions'] = $action_map;
     foreach ($config_info['fields'] as $field => $name) {
         try {
             $field_conditions = $adapter->getConditionsForField($field);
         } catch (Exception $ex) {
             $field_conditions = array(HeraldAdapter::CONDITION_UNCONDITIONALLY);
         }
         $config_info['conditionMap'][$field] = $field_conditions;
     }
     foreach ($config_info['fields'] as $field => $fname) {
         foreach ($config_info['conditionMap'][$field] as $condition) {
             $value_type = $adapter->getValueTypeForFieldAndCondition($field, $condition);
             $config_info['values'][$field][$condition] = $value_type;
         }
     }
     $config_info['rule_type'] = $rule->getRuleType();
     foreach ($config_info['actions'] as $action => $name) {
         try {
             $action_value = $adapter->getValueTypeForAction($action, $rule->getRuleType());
         } catch (Exception $ex) {
             $action_value = array(HeraldAdapter::VALUE_NONE);
         }
         $config_info['targets'][$action] = $action_value;
     }
     $changeflag_options = PhabricatorRepositoryPushLog::getHeraldChangeFlagConditionOptions();
     Javelin::initBehavior('herald-rule-editor', array('root' => 'herald-rule-edit-form', 'conditions' => (object) $serial_conditions, 'actions' => (object) $serial_actions, 'select' => array(HeraldAdapter::VALUE_CONTENT_SOURCE => array('options' => PhabricatorContentSource::getSourceNameMap(), 'default' => PhabricatorContentSource::SOURCE_WEB), HeraldAdapter::VALUE_FLAG_COLOR => array('options' => PhabricatorFlagColor::getColorNameMap(), 'default' => PhabricatorFlagColor::COLOR_BLUE), HeraldPreCommitRefAdapter::VALUE_REF_TYPE => array('options' => array(PhabricatorRepositoryPushLog::REFTYPE_BRANCH => pht('branch (git/hg)'), PhabricatorRepositoryPushLog::REFTYPE_TAG => pht('tag (git)'), PhabricatorRepositoryPushLog::REFTYPE_BOOKMARK => pht('bookmark (hg)')), 'default' => PhabricatorRepositoryPushLog::REFTYPE_BRANCH), HeraldPreCommitRefAdapter::VALUE_REF_CHANGE => array('options' => $changeflag_options, 'default' => PhabricatorRepositoryPushLog::CHANGEFLAG_ADD)), 'template' => $this->buildTokenizerTemplates($handles) + array('rules' => $all_rules), 'author' => array($rule->getAuthorPHID() => $handles[$rule->getAuthorPHID()]->getName()), 'info' => $config_info));
 }
 protected function buildWhereClauseParts(AphrontDatabaseConnection $conn)
 {
     $where = parent::buildWhereClauseParts($conn);
     if ($this->ids !== null) {
         $where[] = qsprintf($conn, 'm.id IN (%Ld)', $this->ids);
     }
     if ($this->phids !== null) {
         $where[] = qsprintf($conn, 'm.phid IN (%Ls)', $this->phids);
     }
     if ($this->authorPHIDs !== null) {
         $where[] = qsprintf($conn, 'm.authorPHID IN (%Ls)', $this->authorPHIDs);
     }
     if (strlen($this->nameLike)) {
         $where[] = qsprintf($conn, 'm.name LIKE %~', $this->nameLike);
     }
     if ($this->names !== null) {
         $where[] = qsprintf($conn, 'm.name IN (%Ls)', $this->names);
     }
     if (strlen($this->namePrefix)) {
         $where[] = qsprintf($conn, 'm.name LIKE %>', $this->namePrefix);
     }
     switch ($this->status) {
         case self::STATUS_ACTIVE:
             $where[] = qsprintf($conn, 'm.isDisabled = 0');
             break;
         case self::STATUS_DISABLED:
             $where[] = qsprintf($conn, 'm.isDisabled = 1');
             break;
         case self::STATUS_ANY:
             break;
         default:
             throw new Exception(pht("Unknown status '%s'!", $this->status));
     }
     if ($this->dateCreatedAfter) {
         $where[] = qsprintf($conn, 'm.dateCreated >= %d', $this->dateCreatedAfter);
     }
     if ($this->dateCreatedBefore) {
         $where[] = qsprintf($conn, 'm.dateCreated <= %d', $this->dateCreatedBefore);
     }
     if ($this->flagColor != '-1' && $this->flagColor !== null) {
         if ($this->flagColor == '-2') {
             $flag_colors = array_keys(PhabricatorFlagColor::getColorNameMap());
         } else {
             $flag_colors = array($this->flagColor);
         }
         $flags = id(new PhabricatorFlagQuery())->withOwnerPHIDs(array($this->getViewer()->getPHID()))->withTypes(array(PhabricatorMacroMacroPHIDType::TYPECONST))->withColors($flag_colors)->setViewer($this->getViewer())->execute();
         if (empty($flags)) {
             throw new PhabricatorEmptyQueryException(pht('No matching flags.'));
         } else {
             $where[] = qsprintf($conn, 'm.phid IN (%Ls)', mpull($flags, 'getObjectPHID'));
         }
     }
     return $where;
 }