From 6172f2bbd18e00164f5f8f86d33c4159e274d8d2 Mon Sep 17 00:00:00 2001 From: epriestley Date: Sun, 28 Jul 2013 16:30:30 -0700 Subject: [PATCH] Require answers' authors to be unique in Ponder Summary: Ref T3578. I forget if this was an explicit decision or not, but we currently let the same user answer questions multiple times. I think this probably causes more confusion than it provides freedom. In conjunction with other UI issues (commenting being weird, notably), we're seeing some use of answers to comment, which is undesirable. Require each answer's author to be unique. Merge existing nonunique authors' answers. Test Plan: {F52062} Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T3578 Differential Revision: https://secure.phabricator.com/D6605 --- .../sql/patches/20130728.ponderunique.php | 58 +++++++++++++++++++ .../sql/patches/20130728.ponderuniquekey.sql | 2 + .../PonderQuestionViewController.php | 30 +++++++--- .../patch/PhabricatorBuiltinPatchList.php | 8 +++ 4 files changed, 89 insertions(+), 9 deletions(-) create mode 100644 resources/sql/patches/20130728.ponderunique.php create mode 100644 resources/sql/patches/20130728.ponderuniquekey.sql diff --git a/resources/sql/patches/20130728.ponderunique.php b/resources/sql/patches/20130728.ponderunique.php new file mode 100644 index 0000000000..94a45ae786 --- /dev/null +++ b/resources/sql/patches/20130728.ponderunique.php @@ -0,0 +1,58 @@ +establishConnection('w'); +$conn_w->openTransaction(); + +$answers = new LiskMigrationIterator(new PonderAnswer()); +foreach ($answers as $answer) { + $aid = $answer->getID(); + $qid = $answer->getQuestionID(); + $author_phid = $answer->getAuthorPHID(); + + echo "Processing answer ID #{$aid}...\n"; + + if (empty($map[$qid][$author_phid])) { + echo "Answer is unique.\n"; + $map[$qid][$author_phid] = $answer; + continue; + } else { + echo "Merging answer.\n"; + $target = $map[$qid][$author_phid]; + queryfx( + $conn_w, + 'UPDATE %T SET content = %s WHERE id = %d', + $target->getTableName(), + + $target->getContent(). + "\n\n". + "---". + "\n\n". + "> (This content was automatically merged from another answer by the ". + "same author.)". + "\n\n". + $answer->getContent(), + + $target->getID()); + + queryfx( + $conn_w, + 'DELETE FROM %T WHERE id = %d', + $target->getTableName(), + $answer->getID()); + + queryfx( + $conn_w, + 'UPDATE %T SET targetPHID = %s WHERE targetPHID = %s', + 'ponder_comment', + $target->getPHID(), + $answer->getPHID()); + } +} + +$conn_w->saveTransaction(); +echo "Done.\n"; diff --git a/resources/sql/patches/20130728.ponderuniquekey.sql b/resources/sql/patches/20130728.ponderuniquekey.sql new file mode 100644 index 0000000000..721be2ff6d --- /dev/null +++ b/resources/sql/patches/20130728.ponderuniquekey.sql @@ -0,0 +1,2 @@ +ALTER TABLE {$NAMESPACE}_ponder.ponder_answer + ADD UNIQUE KEY `key_oneanswerperquestion` (questionID, authorPHID); diff --git a/src/applications/ponder/controller/PonderQuestionViewController.php b/src/applications/ponder/controller/PonderQuestionViewController.php index 1368da6b7d..9f8536c8a0 100644 --- a/src/applications/ponder/controller/PonderQuestionViewController.php +++ b/src/applications/ponder/controller/PonderQuestionViewController.php @@ -27,11 +27,18 @@ final class PonderQuestionViewController extends PonderController { $question_xactions = $this->buildQuestionTransactions($question); $answers = $this->buildAnswers($question->getAnswers()); - $answer_add_panel = new PonderAddAnswerView(); - $answer_add_panel - ->setQuestion($question) - ->setUser($user) - ->setActionURI("/ponder/answer/add/"); + $authors = mpull($question->getAnswers(), null, 'getAuthorPHID'); + if (isset($authors[$user->getPHID()])) { + // TODO: Make this pretty + $answer_add_panel = pht( + 'You have already answered this question.'); + } else { + $answer_add_panel = new PonderAddAnswerView(); + $answer_add_panel + ->setQuestion($question) + ->setUser($user) + ->setActionURI("/ponder/answer/add/"); + } $header = id(new PhabricatorHeaderView()) ->setHeader($question->getTitle()); @@ -268,10 +275,15 @@ final class PonderQuestionViewController extends PonderController { $view->invokeWillRenderEvent(); $view->addTextContent( - PhabricatorMarkupEngine::renderOneObject( - $answer, - $answer->getMarkupField(), - $viewer)); + phutil_tag( + 'div', + array( + 'class' => 'phabricator-remarkup', + ), + PhabricatorMarkupEngine::renderOneObject( + $answer, + $answer->getMarkupField(), + $viewer))); return $view; } diff --git a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php index db34c66d02..31c0bc49f6 100644 --- a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php +++ b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php @@ -1487,6 +1487,14 @@ final class PhabricatorBuiltinPatchList extends PhabricatorSQLPatchList { 'type' => 'sql', 'name' => $this->getPatchPath('20130726.ponderxactions.sql'), ), + '20130728.ponderunique.php' => array( + 'type' => 'php', + 'name' => $this->getPatchPath('20130728.ponderunique.php'), + ), + '20130728.ponderuniquekey.sql' => array( + 'type' => 'sql', + 'name' => $this->getPatchPath('20130728.ponderuniquekey.sql'), + ), ); } }