Page MenuHomePhabricator

D13826.id33394.diff
No OneTemporary

D13826.id33394.diff

diff --git a/resources/sql/autopatches/20150806.ponder.status.1.sql b/resources/sql/autopatches/20150806.ponder.status.1.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20150806.ponder.status.1.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_ponder.ponder_question
+ MODIFY status VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT};
diff --git a/resources/sql/autopatches/20150806.ponder.status.2.sql b/resources/sql/autopatches/20150806.ponder.status.2.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20150806.ponder.status.2.sql
@@ -0,0 +1,2 @@
+UPDATE {$NAMESPACE}_ponder.ponder_question
+ SET status = 'open' WHERE status = 0;
diff --git a/resources/sql/autopatches/20150806.ponder.status.3.sql b/resources/sql/autopatches/20150806.ponder.status.3.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20150806.ponder.status.3.sql
@@ -0,0 +1,2 @@
+UPDATE {$NAMESPACE}_ponder.ponder_question
+ SET status = 'resolved' WHERE status = 1;
diff --git a/src/applications/ponder/application/PhabricatorPonderApplication.php b/src/applications/ponder/application/PhabricatorPonderApplication.php
--- a/src/applications/ponder/application/PhabricatorPonderApplication.php
+++ b/src/applications/ponder/application/PhabricatorPonderApplication.php
@@ -71,7 +71,7 @@
=> 'PonderQuestionHistoryController',
'preview/'
=> 'PhabricatorMarkupPreviewController',
- 'question/(?P<status>open|close)/(?P<id>[1-9]\d*)/'
+ 'question/status/(?P<id>[1-9]\d*)/'
=> 'PonderQuestionStatusController',
'vote/' => 'PonderVoteSaveController',
),
diff --git a/src/applications/ponder/constants/PonderQuestionStatus.php b/src/applications/ponder/constants/PonderQuestionStatus.php
--- a/src/applications/ponder/constants/PonderQuestionStatus.php
+++ b/src/applications/ponder/constants/PonderQuestionStatus.php
@@ -2,20 +2,40 @@
final class PonderQuestionStatus extends PonderConstants {
- const STATUS_OPEN = 0;
- const STATUS_CLOSED = 1;
+ const STATUS_OPEN = 'open';
+ const STATUS_CLOSED_RESOLVED = 'resolved';
+ const STATUS_CLOSED_OBSOLETE = 'obsolete';
+ const STATUS_CLOSED_DUPLICATE = 'duplicate';
public static function getQuestionStatusMap() {
return array(
- self::STATUS_OPEN => pht('Open'),
- self::STATUS_CLOSED => pht('Closed'),
+ 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 => pht('Closed by author'),
+ 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 getQuestionStatusDescription($status) {
+ $map = array(
+ self::STATUS_OPEN =>
+ pht('This question is open for answers.'),
+ self::STATUS_CLOSED_RESOLVED =>
+ pht('This question has been 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'));
}
@@ -23,7 +43,9 @@
public static function getQuestionStatusTagColor($status) {
$map = array(
self::STATUS_OPEN => PHUITagView::COLOR_BLUE,
- self::STATUS_CLOSED => PHUITagView::COLOR_BLACK,
+ 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);
@@ -32,10 +54,27 @@
public static function getQuestionStatusIcon($status) {
$map = array(
self::STATUS_OPEN => 'fa-question-circle',
- self::STATUS_CLOSED => 'fa-check-square-o',
+ 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,
+ );
+ }
+
+
}
diff --git a/src/applications/ponder/controller/PonderQuestionEditController.php b/src/applications/ponder/controller/PonderQuestionEditController.php
--- a/src/applications/ponder/controller/PonderQuestionEditController.php
+++ b/src/applications/ponder/controller/PonderQuestionEditController.php
@@ -33,6 +33,8 @@
$v_view = $question->getViewPolicy();
$v_edit = $question->getEditPolicy();
$v_space = $question->getSpacePHID();
+ $v_status = $question->getStatus();
+
$errors = array();
$e_title = true;
@@ -43,6 +45,7 @@
$v_view = $request->getStr('viewPolicy');
$v_edit = $request->getStr('editPolicy');
$v_space = $request->getStr('spacePHID');
+ $v_status = $request->getStr('status');
$len = phutil_utf8_strlen($v_title);
if ($len < 1) {
@@ -66,6 +69,10 @@
->setNewValue($v_content);
$xactions[] = id(clone $template)
+ ->setTransactionType(PonderQuestionTransaction::TYPE_STATUS)
+ ->setNewValue($v_status);
+
+ $xactions[] = id(clone $template)
->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)
->setNewValue($v_view);
@@ -130,7 +137,13 @@
->setPolicyObject($question)
->setPolicies($policies)
->setValue($v_edit)
- ->setCapability(PhabricatorPolicyCapability::CAN_EDIT));
+ ->setCapability(PhabricatorPolicyCapability::CAN_EDIT))
+ ->appendChild(
+ id(new AphrontFormSelectControl())
+ ->setLabel(pht('Status'))
+ ->setName('status')
+ ->setValue($v_status)
+ ->setOptions(PonderQuestionStatus::getQuestionStatusMap()));
$form->appendControl(
id(new AphrontFormTokenizerControl())
@@ -149,21 +162,23 @@
->setControlID('content')
->setPreviewURI($this->getApplicationURI('preview/'));
- $form_box = id(new PHUIObjectBoxView())
- ->setHeaderText(pht('Ask New Question'))
- ->setFormErrors($errors)
- ->setForm($form);
-
$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,
@@ -171,7 +186,7 @@
$preview,
),
array(
- 'title' => pht('Ask New Question'),
+ 'title' => $title,
));
}
diff --git a/src/applications/ponder/controller/PonderQuestionStatusController.php b/src/applications/ponder/controller/PonderQuestionStatusController.php
--- a/src/applications/ponder/controller/PonderQuestionStatusController.php
+++ b/src/applications/ponder/controller/PonderQuestionStatusController.php
@@ -6,7 +6,6 @@
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
- $status = $request->getURIData('status');
$question = id(new PonderQuestionQuery())
->setViewer($viewer)
@@ -21,29 +20,46 @@
return new Aphront404Response();
}
- switch ($status) {
- case 'open':
- $status = PonderQuestionStatus::STATUS_OPEN;
- break;
- case 'close':
- $status = PonderQuestionStatus::STATUS_CLOSED;
- break;
- default:
- return new Aphront400Response();
+ $view_uri = '/Q'.$question->getID();
+ $v_status = $question->getStatus();
+
+ if ($request->isFormPost()) {
+ $v_status = $request->getStr('status');
+
+ $xactions = array();
+ $xactions[] = id(new PonderQuestionTransaction())
+ ->setTransactionType(PonderQuestionTransaction::TYPE_STATUS)
+ ->setNewValue($v_status);
+
+ $editor = id(new PonderQuestionEditor())
+ ->setActor($viewer)
+ ->setContentSourceFromRequest($request);
+
+ $editor->applyTransactions($question, $xactions);
+
+ return id(new AphrontRedirectResponse())->setURI($view_uri);
}
- $xactions = array();
- $xactions[] = id(new PonderQuestionTransaction())
- ->setTransactionType(PonderQuestionTransaction::TYPE_STATUS)
- ->setNewValue($status);
+ $radio = id(new AphrontFormRadioButtonControl())
+ ->setLabel(pht('Status'))
+ ->setName('status')
+ ->setValue($v_status);
+
+ foreach (PonderQuestionStatus::getQuestionStatusMap() as $value => $name) {
+ $description = PonderQuestionStatus::getQuestionStatusDescription($value);
+ $radio->addButton($value, $name, $description);
+ }
- $editor = id(new PonderQuestionEditor())
- ->setActor($viewer)
- ->setContentSourceFromRequest($request);
+ $form = id(new AphrontFormView())
+ ->setUser($viewer)
+ ->appendChild($radio);
- $editor->applyTransactions($question, $xactions);
+ return $this->newDialog()
+ ->setTitle(pht('Change Question Status'))
+ ->appendChild($form->buildLayoutView())
+ ->addSubmitButton(pht('Submit'))
+ ->addCancelButton($view_uri);
- return id(new AphrontRedirectResponse())->setURI('/Q'.$question->getID());
}
}
diff --git a/src/applications/ponder/controller/PonderQuestionViewController.php b/src/applications/ponder/controller/PonderQuestionViewController.php
--- a/src/applications/ponder/controller/PonderQuestionViewController.php
+++ b/src/applications/ponder/controller/PonderQuestionViewController.php
@@ -45,7 +45,11 @@
if ($question->getStatus() == PonderQuestionStatus::STATUS_OPEN) {
$header->setStatus('fa-square-o', 'bluegrey', pht('Open'));
} else {
- $header->setStatus('fa-check-square-o', 'dark', pht('Closed'));
+ $text = PonderQuestionStatus::getQuestionStatusFullName(
+ $question->getStatus());
+ $icon = PonderQuestionStatus::getQuestionStatusIcon(
+ $question->getStatus());
+ $header->setStatus($icon, 'dark', $text);
}
$actions = $this->buildActionListView($question);
@@ -109,21 +113,18 @@
if ($question->getStatus() == PonderQuestionStatus::STATUS_OPEN) {
$name = pht('Close Question');
$icon = 'fa-check-square-o';
- $href = 'close';
} else {
$name = pht('Reopen Question');
$icon = 'fa-square-o';
- $href = 'open';
}
$view->addAction(
id(new PhabricatorActionView())
->setName($name)
->setIcon($icon)
- ->setRenderAsForm($can_edit)
- ->setWorkflow(!$can_edit)
+ ->setWorkflow(true)
->setDisabled(!$can_edit)
- ->setHref($this->getApplicationURI("/question/{$href}/{$id}/")));
+ ->setHref($this->getApplicationURI("/question/status/{$id}/")));
$view->addAction(
id(new PhabricatorActionView())
diff --git a/src/applications/ponder/query/PonderQuestionQuery.php b/src/applications/ponder/query/PonderQuestionQuery.php
--- a/src/applications/ponder/query/PonderQuestionQuery.php
+++ b/src/applications/ponder/query/PonderQuestionQuery.php
@@ -5,17 +5,12 @@
private $ids;
private $phids;
+ private $status;
private $authorPHIDs;
private $answererPHIDs;
private $needProjectPHIDs;
- private $status = 'status-any';
-
- const STATUS_ANY = 'status-any';
- const STATUS_OPEN = 'status-open';
- const STATUS_CLOSED = 'status-closed';
-
private $needAnswers;
private $needViewerVotes;
@@ -34,7 +29,7 @@
return $this;
}
- public function withStatus($status) {
+ public function withStatuses($status) {
$this->status = $status;
return $this;
}
@@ -84,24 +79,10 @@
}
if ($this->status !== null) {
- switch ($this->status) {
- case self::STATUS_ANY:
- break;
- case self::STATUS_OPEN:
- $where[] = qsprintf(
- $conn,
- 'q.status = %d',
- PonderQuestionStatus::STATUS_OPEN);
- break;
- case self::STATUS_CLOSED:
- $where[] = qsprintf(
- $conn,
- 'q.status = %d',
- PonderQuestionStatus::STATUS_CLOSED);
- break;
- default:
- throw new Exception(pht("Unknown status query '%s'!", $this->status));
- }
+ $where[] = qsprintf(
+ $conn,
+ 'q.status IN (%Ls)',
+ $this->status);
}
return $where;
diff --git a/src/applications/ponder/query/PonderQuestionSearchEngine.php b/src/applications/ponder/query/PonderQuestionSearchEngine.php
--- a/src/applications/ponder/query/PonderQuestionSearchEngine.php
+++ b/src/applications/ponder/query/PonderQuestionSearchEngine.php
@@ -27,16 +27,8 @@
$query->withAnswererPHIDs($map['answerers']);
}
- $status = $map['status'];
- if ($status != null) {
- switch ($status) {
- case 0:
- $query->withStatus(PonderQuestionQuery::STATUS_OPEN);
- break;
- case 1:
- $query->withStatus(PonderQuestionQuery::STATUS_CLOSED);
- break;
- }
+ if ($map['statuses']) {
+ $query->withStatuses($map['statuses']);
}
return $query;
@@ -52,9 +44,9 @@
->setKey('answerers')
->setAliases(array('answerers'))
->setLabel(pht('Answered By')),
- id(new PhabricatorSearchSelectField())
+ id(new PhabricatorSearchCheckboxesField())
->setLabel(pht('Status'))
- ->setKey('status')
+ ->setKey('statuses')
->setOptions(PonderQuestionStatus::getQuestionStatusMap()),
);
}
@@ -66,6 +58,7 @@
protected function getBuiltinQueryNames() {
$names = array(
'open' => pht('Open Questions'),
+ 'resolved' => pht('Resolved Questions'),
'all' => pht('All Questions'),
);
@@ -85,7 +78,11 @@
case 'all':
return $query;
case 'open':
- return $query->setParameter('status', PonderQuestionQuery::STATUS_OPEN);
+ return $query->setParameter(
+ 'statuses', array(PonderQuestionStatus::STATUS_OPEN));
+ case 'resolved':
+ return $query->setParameter(
+ 'statuses', array(PonderQuestionStatus::STATUS_CLOSED_RESOLVED));
case 'authored':
return $query->setParameter(
'authorPHIDs',
diff --git a/src/applications/ponder/storage/PonderQuestion.php b/src/applications/ponder/storage/PonderQuestion.php
--- a/src/applications/ponder/storage/PonderQuestion.php
+++ b/src/applications/ponder/storage/PonderQuestion.php
@@ -65,7 +65,7 @@
self::CONFIG_COLUMN_SCHEMA => array(
'title' => 'text255',
'voteCount' => 'sint32',
- 'status' => 'uint32',
+ 'status' => 'text32',
'content' => 'text',
'heat' => 'double',
'answerCount' => 'uint32',
diff --git a/src/applications/ponder/storage/PonderQuestionTransaction.php b/src/applications/ponder/storage/PonderQuestionTransaction.php
--- a/src/applications/ponder/storage/PonderQuestionTransaction.php
+++ b/src/applications/ponder/storage/PonderQuestionTransaction.php
@@ -87,9 +87,17 @@
return pht(
'%s reopened this question.',
$this->renderHandleLink($author_phid));
- case PonderQuestionStatus::STATUS_CLOSED:
+ case PonderQuestionStatus::STATUS_CLOSED_RESOLVED:
+ return pht(
+ '%s closed this question as resolved.',
+ $this->renderHandleLink($author_phid));
+ case PonderQuestionStatus::STATUS_CLOSED_OBSOLETE:
return pht(
- '%s closed this question.',
+ '%s closed this question as obsolete.',
+ $this->renderHandleLink($author_phid));
+ case PonderQuestionStatus::STATUS_CLOSED_DUPLICATE:
+ return pht(
+ '%s closed this question as a duplicate.',
$this->renderHandleLink($author_phid));
}
}
@@ -106,12 +114,7 @@
case self::TYPE_CONTENT:
return 'fa-pencil';
case self::TYPE_STATUS:
- switch ($new) {
- case PonderQuestionStatus::STATUS_OPEN:
- return 'fa-check-circle';
- case PonderQuestionStatus::STATUS_CLOSED:
- return 'fa-minus-circle';
- }
+ return PonderQuestionStatus::getQuestionStatusIcon($new);
case self::TYPE_ANSWERS:
return 'fa-plus';
}
@@ -130,12 +133,7 @@
case self::TYPE_ANSWERS:
return PhabricatorTransactions::COLOR_GREEN;
case self::TYPE_STATUS:
- switch ($new) {
- case PonderQuestionStatus::STATUS_OPEN:
- return PhabricatorTransactions::COLOR_GREEN;
- case PonderQuestionStatus::STATUS_CLOSED:
- return PhabricatorTransactions::COLOR_INDIGO;
- }
+ return PonderQuestionStatus::getQuestionStatusTagColor($new);
}
}

File Metadata

Mime Type
text/plain
Expires
Wed, May 22, 1:33 AM (3 w, 4 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6294294
Default Alt Text
D13826.id33394.diff (17 KB)

Event Timeline