Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/ponder/constants/PonderQuestionStatus.php b/src/applications/ponder/constants/PonderQuestionStatus.php
index 917539f81b..61a446353e 100644
--- a/src/applications/ponder/constants/PonderQuestionStatus.php
+++ b/src/applications/ponder/constants/PonderQuestionStatus.php
@@ -1,108 +1,89 @@
<?php
final class PonderQuestionStatus extends PonderConstants {
const STATUS_OPEN = 'open';
const STATUS_CLOSED_RESOLVED = 'resolved';
const STATUS_CLOSED_OBSOLETE = 'obsolete';
const STATUS_CLOSED_DUPLICATE = 'duplicate';
- const ANSWER_STATUS_VISIBLE = 'visible';
- const ANSWER_STATUS_HIDDEN = 'hidden';
-
public static function getQuestionStatusMap() {
return array(
self::STATUS_OPEN => pht('Open'),
self::STATUS_CLOSED_RESOLVED => pht('Closed, Resolved'),
self::STATUS_CLOSED_OBSOLETE => pht('Closed, Obsolete'),
self::STATUS_CLOSED_DUPLICATE => pht('Closed, Duplicate'),
);
}
public static function getQuestionStatusFullName($status) {
$map = array(
self::STATUS_OPEN => pht('Open'),
self::STATUS_CLOSED_RESOLVED => pht('Closed, Resolved'),
self::STATUS_CLOSED_OBSOLETE => pht('Closed, Obsolete'),
self::STATUS_CLOSED_DUPLICATE => pht('Closed, Duplicate'),
);
return idx($map, $status, pht('Unknown'));
}
public static function getQuestionStatusName($status) {
$map = array(
self::STATUS_OPEN => pht('Open'),
self::STATUS_CLOSED_RESOLVED => pht('Resolved'),
self::STATUS_CLOSED_OBSOLETE => pht('Obsolete'),
self::STATUS_CLOSED_DUPLICATE => pht('Duplicate'),
);
return idx($map, $status, pht('Unknown'));
}
public static function getQuestionStatusDescription($status) {
$map = array(
self::STATUS_OPEN =>
pht('This question is open for answers.'),
self::STATUS_CLOSED_RESOLVED =>
pht('This question has been answered or resolved.'),
self::STATUS_CLOSED_OBSOLETE =>
pht('This question is no longer valid or out of date.'),
self::STATUS_CLOSED_DUPLICATE =>
pht('This question is a duplicate of another question.'),
);
return idx($map, $status, pht('Unknown'));
}
public static function getQuestionStatusTagColor($status) {
$map = array(
self::STATUS_OPEN => PHUITagView::COLOR_BLUE,
self::STATUS_CLOSED_RESOLVED => PHUITagView::COLOR_BLACK,
self::STATUS_CLOSED_OBSOLETE => PHUITagView::COLOR_BLACK,
self::STATUS_CLOSED_DUPLICATE => PHUITagView::COLOR_BLACK,
);
return idx($map, $status);
}
public static function getQuestionStatusIcon($status) {
$map = array(
self::STATUS_OPEN => 'fa-question-circle',
self::STATUS_CLOSED_RESOLVED => 'fa-check',
self::STATUS_CLOSED_OBSOLETE => 'fa-ban',
self::STATUS_CLOSED_DUPLICATE => 'fa-clone',
);
return idx($map, $status);
}
public static function getQuestionStatusOpenMap() {
return array(
self::STATUS_OPEN,
);
}
public static function getQuestionStatusClosedMap() {
return array(
self::STATUS_CLOSED_RESOLVED,
self::STATUS_CLOSED_OBSOLETE,
self::STATUS_CLOSED_DUPLICATE,
);
}
- public static function getAnswerStatusMap() {
- return array(
- self::ANSWER_STATUS_VISIBLE => pht('Visible'),
- self::ANSWER_STATUS_HIDDEN => pht('Hidden'),
- );
- }
-
- public static function getAnswerStatusName($status) {
- $map = array(
- self::ANSWER_STATUS_VISIBLE => pht('Visible'),
- self::ANSWER_STATUS_HIDDEN => pht('Hidden'),
- );
- return idx($map, $status, pht('Unknown'));
- }
-
-
}
diff --git a/src/applications/ponder/controller/PonderQuestionEditController.php b/src/applications/ponder/controller/PonderQuestionEditController.php
index 71b9615cca..41123d6049 100644
--- a/src/applications/ponder/controller/PonderQuestionEditController.php
+++ b/src/applications/ponder/controller/PonderQuestionEditController.php
@@ -1,186 +1,188 @@
<?php
final class PonderQuestionEditController extends PonderController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
if ($id) {
$question = id(new PonderQuestionQuery())
->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$question) {
return new Aphront404Response();
}
$v_projects = PhabricatorEdgeQuery::loadDestinationPHIDs(
$question->getPHID(),
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
$v_projects = array_reverse($v_projects);
$is_new = false;
} else {
$is_new = true;
$question = PonderQuestion::initializeNewQuestion($viewer);
$v_projects = array();
}
$v_title = $question->getTitle();
$v_content = $question->getContent();
$v_view = $question->getViewPolicy();
$v_space = $question->getSpacePHID();
$v_status = $question->getStatus();
$errors = array();
$e_title = true;
if ($request->isFormPost()) {
$v_title = $request->getStr('title');
$v_content = $request->getStr('content');
$v_projects = $request->getArr('projects');
$v_view = $request->getStr('viewPolicy');
$v_space = $request->getStr('spacePHID');
$v_status = $request->getStr('status');
$len = phutil_utf8_strlen($v_title);
if ($len < 1) {
$errors[] = pht('Title must not be empty.');
$e_title = pht('Required');
} else if ($len > 255) {
$errors[] = pht('Title is too long.');
$e_title = pht('Too Long');
}
if (!$errors) {
$template = id(new PonderQuestionTransaction());
$xactions = array();
$xactions[] = id(clone $template)
->setTransactionType(PonderQuestionTransaction::TYPE_TITLE)
->setNewValue($v_title);
$xactions[] = id(clone $template)
->setTransactionType(PonderQuestionTransaction::TYPE_CONTENT)
->setNewValue($v_content);
- $xactions[] = id(clone $template)
- ->setTransactionType(PonderQuestionTransaction::TYPE_STATUS)
- ->setNewValue($v_status);
+ if (!$is_new) {
+ $xactions[] = id(clone $template)
+ ->setTransactionType(PonderQuestionTransaction::TYPE_STATUS)
+ ->setNewValue($v_status);
+ }
$xactions[] = id(clone $template)
->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)
->setNewValue($v_view);
$xactions[] = id(clone $template)
->setTransactionType(PhabricatorTransactions::TYPE_SPACE)
->setNewValue($v_space);
$proj_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
$xactions[] = id(new PonderQuestionTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
->setMetadataValue('edge:type', $proj_edge_type)
->setNewValue(array('=' => array_fuse($v_projects)));
$editor = id(new PonderQuestionEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true);
$editor->applyTransactions($question, $xactions);
return id(new AphrontRedirectResponse())
->setURI('/Q'.$question->getID());
}
}
$policies = id(new PhabricatorPolicyQuery())
->setViewer($viewer)
->setObject($question)
->execute();
$form = id(new AphrontFormView())
->setUser($viewer)
->appendChild(
id(new AphrontFormTextControl())
->setLabel(pht('Question'))
->setName('title')
->setValue($v_title)
->setError($e_title))
->appendChild(
id(new PhabricatorRemarkupControl())
->setUser($viewer)
->setName('content')
->setID('content')
->setValue($v_content)
->setLabel(pht('Description'))
->setUser($viewer))
->appendControl(
id(new AphrontFormPolicyControl())
->setName('viewPolicy')
->setPolicyObject($question)
->setSpacePHID($v_space)
->setPolicies($policies)
->setValue($v_view)
->setCapability(PhabricatorPolicyCapability::CAN_VIEW));
if (!$is_new) {
$form->appendChild(
id(new AphrontFormSelectControl())
->setLabel(pht('Status'))
->setName('status')
->setValue($v_status)
->setOptions(PonderQuestionStatus::getQuestionStatusMap()));
}
$form->appendControl(
id(new AphrontFormTokenizerControl())
->setLabel(pht('Projects'))
->setName('projects')
->setValue($v_projects)
->setDatasource(new PhabricatorProjectDatasource()));
$form->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton($this->getApplicationURI())
->setValue(pht('Submit')));
$preview = id(new PHUIRemarkupPreviewPanel())
->setHeader(pht('Question Preview'))
->setControlID('content')
->setPreviewURI($this->getApplicationURI('preview/'));
$crumbs = $this->buildApplicationCrumbs();
$id = $question->getID();
if ($id) {
$crumbs->addTextCrumb("Q{$id}", "/Q{$id}");
$crumbs->addTextCrumb(pht('Edit'));
$title = pht('Edit Question');
} else {
$crumbs->addTextCrumb(pht('Ask Question'));
$title = pht('Ask New Question');
}
$form_box = id(new PHUIObjectBoxView())
->setHeaderText($title)
->setFormErrors($errors)
->setForm($form);
return $this->buildApplicationPage(
array(
$crumbs,
$form_box,
$preview,
),
array(
'title' => $title,
));
}
}
diff --git a/src/applications/ponder/controller/PonderQuestionViewController.php b/src/applications/ponder/controller/PonderQuestionViewController.php
index a1e526648d..06f924510f 100644
--- a/src/applications/ponder/controller/PonderQuestionViewController.php
+++ b/src/applications/ponder/controller/PonderQuestionViewController.php
@@ -1,282 +1,285 @@
<?php
final class PonderQuestionViewController extends PonderController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
$question = id(new PonderQuestionQuery())
->setViewer($viewer)
->withIDs(array($id))
->needAnswers(true)
->needProjectPHIDs(true)
->executeOne();
if (!$question) {
return new Aphront404Response();
}
$answers = $this->buildAnswers($question->getAnswers());
$answer_add_panel = id(new PonderAddAnswerView())
->setQuestion($question)
->setUser($viewer)
->setActionURI('/ponder/answer/add/');
$header = new PHUIHeaderView();
$header->setHeader($question->getTitle());
$header->setUser($viewer);
$header->setPolicyObject($question);
if ($question->getStatus() == PonderQuestionStatus::STATUS_OPEN) {
$header->setStatus('fa-square-o', 'bluegrey', pht('Open'));
} else {
$text = PonderQuestionStatus::getQuestionStatusFullName(
$question->getStatus());
$icon = PonderQuestionStatus::getQuestionStatusIcon(
$question->getStatus());
$header->setStatus($icon, 'dark', $text);
}
$actions = $this->buildActionListView($question);
$properties = $this->buildPropertyListView($question, $actions);
$sidebar = $this->buildSidebar($question);
$content_id = celerity_generate_unique_node_id();
$timeline = $this->buildTransactionTimeline(
$question,
id(new PonderQuestionTransactionQuery())
->withTransactionTypes(array(PhabricatorTransactions::TYPE_COMMENT)));
$xactions = $timeline->getTransactions();
$add_comment = id(new PhabricatorApplicationTransactionCommentView())
->setUser($viewer)
->setObjectPHID($question->getPHID())
->setShowPreview(false)
->setHeaderText(pht('Question Comment'))
->setAction($this->getApplicationURI("/question/comment/{$id}/"))
->setSubmitButtonName(pht('Comment'));
$comment_view = phutil_tag(
'div',
array(
'id' => $content_id,
'style' => 'display: none;',
),
array(
$timeline,
$add_comment,
));
$footer = id(new PonderFooterView())
->setContentID($content_id)
->setCount(count($xactions));
$object_box = id(new PHUIObjectBoxView())
->setHeader($header)
->addPropertyList($properties)
->appendChild($footer);
$crumbs = $this->buildApplicationCrumbs($this->buildSideNavView());
$crumbs->addTextCrumb('Q'.$id, '/Q'.$id);
$ponder_view = id(new PHUITwoColumnView())
->setMainColumn(array(
$object_box,
$comment_view,
$answers,
$answer_add_panel,
))
->setSideColumn($sidebar)
->addClass('ponder-question-view');
return $this->buildApplicationPage(
array(
$crumbs,
$ponder_view,
),
array(
'title' => 'Q'.$question->getID().' '.$question->getTitle(),
'pageObjects' => array_merge(
array($question->getPHID()),
mpull($question->getAnswers(), 'getPHID')),
));
}
private function buildActionListView(PonderQuestion $question) {
$viewer = $this->getViewer();
$request = $this->getRequest();
$id = $question->getID();
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$question,
PhabricatorPolicyCapability::CAN_EDIT);
$view = id(new PhabricatorActionListView())
->setUser($viewer)
->setObject($question)
->setObjectURI($request->getRequestURI());
$view->addAction(
id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Question'))
->setHref($this->getApplicationURI("/question/edit/{$id}/"))
->setDisabled(!$can_edit)
->setWorkflow(!$can_edit));
if ($question->getStatus() == PonderQuestionStatus::STATUS_OPEN) {
$name = pht('Close Question');
$icon = 'fa-check-square-o';
} else {
$name = pht('Reopen Question');
$icon = 'fa-square-o';
}
$view->addAction(
id(new PhabricatorActionView())
->setName($name)
->setIcon($icon)
->setWorkflow(true)
->setDisabled(!$can_edit)
->setHref($this->getApplicationURI("/question/status/{$id}/")));
$view->addAction(
id(new PhabricatorActionView())
->setIcon('fa-list')
->setName(pht('View History'))
->setHref($this->getApplicationURI("/question/history/{$id}/")));
return $view;
}
private function buildPropertyListView(
PonderQuestion $question,
PhabricatorActionListView $actions) {
$viewer = $this->getViewer();
$view = id(new PHUIPropertyListView())
->setUser($viewer)
->setObject($question)
->setActionList($actions);
$view->addProperty(
pht('Author'),
$viewer->renderHandle($question->getAuthorPHID()));
$view->addProperty(
pht('Created'),
phabricator_datetime($question->getDateCreated(), $viewer));
$view->invokeWillRenderEvent();
- $view->addSectionHeader(
- pht('Details'),
- PHUIPropertyListView::ICON_SUMMARY);
-
- $view->addTextContent(
- array(
- phutil_tag(
- 'div',
- array(
- 'class' => 'phabricator-remarkup',
- ),
- PhabricatorMarkupEngine::renderOneObject(
+ $details = PhabricatorMarkupEngine::renderOneObject(
$question,
$question->getMarkupField(),
- $viewer)),
- ));
+ $viewer);
+ if ($details) {
+ $view->addSectionHeader(
+ pht('Details'),
+ PHUIPropertyListView::ICON_SUMMARY);
+
+ $view->addTextContent(
+ array(
+ phutil_tag(
+ 'div',
+ array(
+ 'class' => 'phabricator-remarkup',
+ ),
+ $details),
+ ));
+ }
return $view;
}
/**
* This is fairly non-standard; building N timelines at once (N = number of
* answers) is tricky business.
*
* TODO - re-factor this to ajax in one answer panel at a time in a more
* standard fashion. This is necessary to scale this application.
*/
private function buildAnswers(array $answers) {
$viewer = $this->getViewer();
$xactions = id(new PonderAnswerTransactionQuery())
->setViewer($viewer)
->withTransactionTypes(array(PhabricatorTransactions::TYPE_COMMENT))
->withObjectPHIDs(mpull($answers, 'getPHID'))
->execute();
$engine = id(new PhabricatorMarkupEngine())
->setViewer($viewer);
foreach ($xactions as $xaction) {
if ($xaction->getComment()) {
$engine->addObject(
$xaction->getComment(),
PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT);
}
}
$engine->process();
$xaction_groups = mgroup($xactions, 'getObjectPHID');
$view = array();
foreach ($answers as $answer) {
$xactions = idx($xaction_groups, $answer->getPHID(), array());
$id = $answer->getID();
$view[] = id(new PonderAnswerView())
->setUser($viewer)
->setAnswer($answer)
->setTransactions($xactions)
->setMarkupEngine($engine);
}
return $view;
}
private function buildSidebar(PonderQuestion $question) {
$viewer = $this->getViewer();
$status = $question->getStatus();
$id = $question->getID();
$questions = id(new PonderQuestionQuery())
->setViewer($viewer)
->withStatuses(array($status))
->withEdgeLogicPHIDs(
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST,
PhabricatorQueryConstraint::OPERATOR_OR,
$question->getProjectPHIDs())
->setLimit(10)
->execute();
$list = id(new PHUIObjectItemListView())
->setUser($viewer)
->setNoDataString(pht('No similar questions found.'));
foreach ($questions as $question) {
if ($id == $question->getID()) {
continue;
}
$item = new PHUIObjectItemView();
$item->setObjectName('Q'.$question->getID());
$item->setHeader($question->getTitle());
$item->setHref('/Q'.$question->getID());
$item->setObject($question);
$item->addAttribute(
pht('%d Answer(s)', $question->getAnswerCount()));
$list->addItem($item);
}
$box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Similar Questions'))
->setObjectList($list);
return $box;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Wed, Jul 2, 3:12 AM (1 d, 10 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
164642
Default Alt Text
(19 KB)

Event Timeline