diff --git a/resources/sql/autopatches/20150812.ponder.answer.1.sql b/resources/sql/autopatches/20150812.ponder.answer.1.sql new file mode 100644 index 0000000000..1cad5667b9 --- /dev/null +++ b/resources/sql/autopatches/20150812.ponder.answer.1.sql @@ -0,0 +1,2 @@ +ALTER TABLE {$NAMESPACE}_ponder.ponder_answer + ADD status VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT}; diff --git a/resources/sql/autopatches/20150812.ponder.answer.2.sql b/resources/sql/autopatches/20150812.ponder.answer.2.sql new file mode 100644 index 0000000000..ded0b765d5 --- /dev/null +++ b/resources/sql/autopatches/20150812.ponder.answer.2.sql @@ -0,0 +1,2 @@ +UPDATE {$NAMESPACE}_ponder.ponder_answer + SET status = 'visible' WHERE status = ''; diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index ef35408192..3bb3ad8c5b 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -3395,6 +3395,7 @@ phutil_register_library_map(array( 'PonderAnswerPHIDType' => 'applications/ponder/phid/PonderAnswerPHIDType.php', 'PonderAnswerQuery' => 'applications/ponder/query/PonderAnswerQuery.php', 'PonderAnswerSaveController' => 'applications/ponder/controller/PonderAnswerSaveController.php', + 'PonderAnswerStatus' => 'applications/ponder/constants/PonderAnswerStatus.php', 'PonderAnswerTransaction' => 'applications/ponder/storage/PonderAnswerTransaction.php', 'PonderAnswerTransactionComment' => 'applications/ponder/storage/PonderAnswerTransactionComment.php', 'PonderAnswerTransactionQuery' => 'applications/ponder/query/PonderAnswerTransactionQuery.php', @@ -7581,6 +7582,7 @@ phutil_register_library_map(array( 'PonderAnswerPHIDType' => 'PhabricatorPHIDType', 'PonderAnswerQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PonderAnswerSaveController' => 'PonderController', + 'PonderAnswerStatus' => 'PonderConstants', 'PonderAnswerTransaction' => 'PhabricatorApplicationTransaction', 'PonderAnswerTransactionComment' => 'PhabricatorApplicationTransactionComment', 'PonderAnswerTransactionQuery' => 'PhabricatorApplicationTransactionQuery', diff --git a/src/applications/ponder/constants/PonderAnswerStatus.php b/src/applications/ponder/constants/PonderAnswerStatus.php new file mode 100644 index 0000000000..f0f30f30a7 --- /dev/null +++ b/src/applications/ponder/constants/PonderAnswerStatus.php @@ -0,0 +1,24 @@ + 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/constants/PonderQuestionStatus.php b/src/applications/ponder/constants/PonderQuestionStatus.php index c401d52234..917539f81b 100644 --- a/src/applications/ponder/constants/PonderQuestionStatus.php +++ b/src/applications/ponder/constants/PonderQuestionStatus.php @@ -7,6 +7,9 @@ final class PonderQuestionStatus extends PonderConstants { 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'), @@ -86,5 +89,20 @@ final class PonderQuestionStatus extends PonderConstants { ); } + 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/PonderAnswerEditController.php b/src/applications/ponder/controller/PonderAnswerEditController.php index 328eed1f91..ff2fd35920 100644 --- a/src/applications/ponder/controller/PonderAnswerEditController.php +++ b/src/applications/ponder/controller/PonderAnswerEditController.php @@ -20,6 +20,7 @@ final class PonderAnswerEditController extends PonderController { } $v_content = $answer->getContent(); + $v_status = $answer->getStatus(); $e_content = true; @@ -31,6 +32,7 @@ final class PonderAnswerEditController extends PonderController { $errors = array(); if ($request->isFormPost()) { $v_content = $request->getStr('content'); + $v_status = $request->getStr('status'); if (!strlen($v_content)) { $errors[] = pht('You must provide some substance in your answer.'); @@ -43,6 +45,10 @@ final class PonderAnswerEditController extends PonderController { ->setTransactionType(PonderAnswerTransaction::TYPE_CONTENT) ->setNewValue($v_content); + $xactions[] = id(new PonderAnswerTransaction()) + ->setTransactionType(PonderAnswerTransaction::TYPE_STATUS) + ->setNewValue($v_status); + $editor = id(new PonderAnswerEditor()) ->setActor($viewer) ->setContentSourceFromRequest($request) @@ -63,6 +69,12 @@ final class PonderAnswerEditController extends PonderController { id(new AphrontFormStaticControl()) ->setLabel(pht('Question')) ->setValue($question->getTitle())) + ->appendChild( + id(new AphrontFormSelectControl()) + ->setLabel(pht('Status')) + ->setName('status') + ->setValue($v_status) + ->setOptions(PonderAnswerStatus::getAnswerStatusMap())) ->appendChild( id(new PhabricatorRemarkupControl()) ->setUser($viewer) @@ -73,7 +85,7 @@ final class PonderAnswerEditController extends PonderController { ->setError($e_content)) ->appendChild( id(new AphrontFormSubmitControl()) - ->setValue(pht('Update Answer')) + ->setValue(pht('Submit')) ->addCancelButton($answer_uri)); $crumbs = $this->buildApplicationCrumbs(); diff --git a/src/applications/ponder/editor/PonderAnswerEditor.php b/src/applications/ponder/editor/PonderAnswerEditor.php index 9eea95c511..b9e3c42869 100644 --- a/src/applications/ponder/editor/PonderAnswerEditor.php +++ b/src/applications/ponder/editor/PonderAnswerEditor.php @@ -12,6 +12,7 @@ final class PonderAnswerEditor extends PonderEditor { $types[] = PhabricatorTransactions::TYPE_COMMENT; $types[] = PonderAnswerTransaction::TYPE_CONTENT; + $types[] = PonderAnswerTransaction::TYPE_STATUS; $types[] = PonderAnswerTransaction::TYPE_QUESTION_ID; return $types; @@ -23,6 +24,7 @@ final class PonderAnswerEditor extends PonderEditor { switch ($xaction->getTransactionType()) { case PonderAnswerTransaction::TYPE_CONTENT: + case PonderAnswerTransaction::TYPE_STATUS: return $object->getContent(); case PonderAnswerTransaction::TYPE_QUESTION_ID: return $object->getQuestionID(); @@ -35,6 +37,7 @@ final class PonderAnswerEditor extends PonderEditor { switch ($xaction->getTransactionType()) { case PonderAnswerTransaction::TYPE_CONTENT: + case PonderAnswerTransaction::TYPE_STATUS: case PonderAnswerTransaction::TYPE_QUESTION_ID: return $xaction->getNewValue(); } @@ -48,6 +51,9 @@ final class PonderAnswerEditor extends PonderEditor { case PonderAnswerTransaction::TYPE_CONTENT: $object->setContent($xaction->getNewValue()); break; + case PonderAnswerTransaction::TYPE_STATUS: + $object->setStatus($xaction->getNewValue()); + break; case PonderAnswerTransaction::TYPE_QUESTION_ID: $object->setQuestionID($xaction->getNewValue()); break; diff --git a/src/applications/ponder/storage/PonderAnswer.php b/src/applications/ponder/storage/PonderAnswer.php index 42ba5f3816..2c8aff23da 100644 --- a/src/applications/ponder/storage/PonderAnswer.php +++ b/src/applications/ponder/storage/PonderAnswer.php @@ -17,8 +17,9 @@ final class PonderAnswer extends PonderDAO protected $content; protected $mailKey; - + protected $status; protected $voteCount; + private $vote; private $question = self::ATTACHABLE; private $comments; @@ -35,7 +36,8 @@ final class PonderAnswer extends PonderDAO ->setQuestionID(0) ->setContent('') ->setAuthorPHID($actor->getPHID()) - ->setVoteCount(0); + ->setVoteCount(0) + ->setStatus(PonderAnswerStatus::ANSWER_STATUS_VISIBLE); } @@ -84,6 +86,7 @@ final class PonderAnswer extends PonderDAO self::CONFIG_COLUMN_SCHEMA => array( 'voteCount' => 'sint32', 'content' => 'text', + 'status' => 'text32', 'mailKey' => 'bytes20', ), self::CONFIG_KEY_SCHEMA => array( @@ -102,6 +105,9 @@ final class PonderAnswer extends PonderDAO 'authorPHID' => array( 'columns' => array('authorPHID'), ), + 'status' => array( + 'columns' => array('status'), + ), ), ) + parent::getConfiguration(); } diff --git a/src/applications/ponder/storage/PonderAnswerTransaction.php b/src/applications/ponder/storage/PonderAnswerTransaction.php index 07b9768c82..c13cb07b87 100644 --- a/src/applications/ponder/storage/PonderAnswerTransaction.php +++ b/src/applications/ponder/storage/PonderAnswerTransaction.php @@ -4,6 +4,7 @@ final class PonderAnswerTransaction extends PhabricatorApplicationTransaction { const TYPE_CONTENT = 'ponder.answer:content'; + const TYPE_STATUS = 'ponder.answer:status'; const TYPE_QUESTION_ID = 'ponder.answer:question-id'; public function getApplicationName() { @@ -27,6 +28,7 @@ final class PonderAnswerTransaction switch ($this->getTransactionType()) { case self::TYPE_CONTENT: + case self::TYPE_STATUS: $phids[] = $this->getObjectPHID(); break; } @@ -75,6 +77,19 @@ final class PonderAnswerTransaction $this->renderHandleLink($object_phid)); } break; + case self::TYPE_STATUS: + if ($new == PonderAnswerStatus::ANSWER_STATUS_VISIBLE) { + return pht( + '%s marked %s as visible.', + $this->renderHandleLink($author_phid), + $this->renderHandleLink($object_phid)); + } else if ($new == PonderAnswerStatus::ANSWER_STATUS_HIDDEN) { + return pht( + '%s marked %s as hidden.', + $this->renderHandleLink($author_phid), + $this->renderHandleLink($object_phid)); + } + break; } return parent::getTitle(); @@ -101,6 +116,19 @@ final class PonderAnswerTransaction $this->renderHandleLink($object_phid)); } break; + case self::TYPE_STATUS: + if ($new == PonderAnswerStatus::ANSWER_STATUS_VISIBLE) { + return pht( + '%s marked %s as visible.', + $this->renderHandleLink($author_phid), + $this->renderHandleLink($object_phid)); + } else if ($new == PonderAnswerStatus::ANSWER_STATUS_HIDDEN) { + return pht( + '%s marked %s as hidden.', + $this->renderHandleLink($author_phid), + $this->renderHandleLink($object_phid)); + } + break; } return parent::getTitleForFeed(); diff --git a/src/applications/ponder/view/PonderAnswerView.php b/src/applications/ponder/view/PonderAnswerView.php index 435a613828..532bc9f2cd 100644 --- a/src/applications/ponder/view/PonderAnswerView.php +++ b/src/applications/ponder/view/PonderAnswerView.php @@ -31,8 +31,37 @@ final class PonderAnswerView extends AphrontTagView { require_celerity_resource('ponder-view-css'); $answer = $this->answer; $viewer = $this->getUser(); + $status = $answer->getStatus(); $author_phid = $answer->getAuthorPHID(); $actions = $this->buildAnswerActions(); + $id = $answer->getID(); + + if ($status == PonderAnswerStatus::ANSWER_STATUS_HIDDEN) { + $can_edit = PhabricatorPolicyFilter::hasCapability( + $viewer, + $answer, + PhabricatorPolicyCapability::CAN_EDIT); + + $message = array(); + $message[] = phutil_tag( + 'em', + array(), + pht('This answer has been hidden.')); + + if ($can_edit) { + $message[] = phutil_tag( + 'a', + array( + 'href' => "/ponder/answer/edit/{$id}/", + ), + pht('Edit Answer')); + } + $message = phutil_implode_html(' ', $message); + + return id(new PHUIInfoView()) + ->setSeverity(PHUIInfoView::SEVERITY_NODATA) + ->appendChild($message); + } $action_button = id(new PHUIButtonView()) ->setTag('a') @@ -57,7 +86,6 @@ final class PonderAnswerView extends AphrontTagView { $answer->getMarkupField(), $viewer)); - $id = $answer->getID(); $anchor = id(new PhabricatorAnchorView()) ->setAnchorName("A$id");