mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 08:52:39 +01:00
Modernize PonderQuestion with EditEngine
Summary: Just a small touch up to move this to edit engine. Test Plan: - Create a question - Edit a question - Close question - Test NUX state Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D17812
This commit is contained in:
parent
4aec809b69
commit
d467a9e337
9 changed files with 170 additions and 242 deletions
|
@ -4606,6 +4606,7 @@ phutil_register_library_map(array(
|
|||
'PonderQuestionContentTransaction' => 'applications/ponder/xaction/PonderQuestionContentTransaction.php',
|
||||
'PonderQuestionCreateMailReceiver' => 'applications/ponder/mail/PonderQuestionCreateMailReceiver.php',
|
||||
'PonderQuestionEditController' => 'applications/ponder/controller/PonderQuestionEditController.php',
|
||||
'PonderQuestionEditEngine' => 'applications/ponder/editor/PonderQuestionEditEngine.php',
|
||||
'PonderQuestionEditor' => 'applications/ponder/editor/PonderQuestionEditor.php',
|
||||
'PonderQuestionFulltextEngine' => 'applications/ponder/search/PonderQuestionFulltextEngine.php',
|
||||
'PonderQuestionHistoryController' => 'applications/ponder/controller/PonderQuestionHistoryController.php',
|
||||
|
@ -10194,6 +10195,7 @@ phutil_register_library_map(array(
|
|||
'PonderQuestionContentTransaction' => 'PonderQuestionTransactionType',
|
||||
'PonderQuestionCreateMailReceiver' => 'PhabricatorMailReceiver',
|
||||
'PonderQuestionEditController' => 'PonderController',
|
||||
'PonderQuestionEditEngine' => 'PhabricatorEditEngine',
|
||||
'PonderQuestionEditor' => 'PonderEditor',
|
||||
'PonderQuestionFulltextEngine' => 'PhabricatorFulltextEngine',
|
||||
'PonderQuestionHistoryController' => 'PonderController',
|
||||
|
|
|
@ -60,22 +60,26 @@ final class PhabricatorPonderApplication extends PhabricatorApplication {
|
|||
'/ponder/' => array(
|
||||
'(?:query/(?P<queryKey>[^/]+)/)?'
|
||||
=> 'PonderQuestionListController',
|
||||
'answer/add/'
|
||||
=> 'PonderAnswerSaveController',
|
||||
'answer/edit/(?P<id>\d+)/'
|
||||
=> 'PonderAnswerEditController',
|
||||
'answer/comment/(?P<id>\d+)/'
|
||||
=> 'PonderAnswerCommentController',
|
||||
'answer/history/(?P<id>\d+)/'
|
||||
=> 'PonderAnswerHistoryController',
|
||||
'question/edit/(?:(?P<id>\d+)/)?'
|
||||
=> 'PonderQuestionEditController',
|
||||
'question/create/'
|
||||
=> 'PonderQuestionEditController',
|
||||
'question/comment/(?P<id>\d+)/'
|
||||
=> 'PonderQuestionCommentController',
|
||||
'question/history/(?P<id>\d+)/'
|
||||
=> 'PonderQuestionHistoryController',
|
||||
'answer/' => array(
|
||||
'add/'
|
||||
=> 'PonderAnswerSaveController',
|
||||
'edit/(?P<id>\d+)/'
|
||||
=> 'PonderAnswerEditController',
|
||||
'comment/(?P<id>\d+)/'
|
||||
=> 'PonderAnswerCommentController',
|
||||
'history/(?P<id>\d+)/'
|
||||
=> 'PonderAnswerHistoryController',
|
||||
),
|
||||
'question/' => array(
|
||||
$this->getEditRoutePattern('edit/')
|
||||
=> 'PonderQuestionEditController',
|
||||
'create/'
|
||||
=> 'PonderQuestionEditController',
|
||||
'comment/(?P<id>\d+)/'
|
||||
=> 'PonderQuestionCommentController',
|
||||
'history/(?P<id>\d+)/'
|
||||
=> 'PonderQuestionHistoryController',
|
||||
),
|
||||
'preview/'
|
||||
=> 'PhabricatorMarkupPreviewController',
|
||||
'question/status/(?P<id>[1-9]\d*)/'
|
||||
|
|
|
@ -27,13 +27,9 @@ abstract class PonderController extends PhabricatorController {
|
|||
|
||||
protected function buildApplicationCrumbs() {
|
||||
$crumbs = parent::buildApplicationCrumbs();
|
||||
$href = $this->getApplicationURI('question/create/');
|
||||
$crumbs
|
||||
->addAction(
|
||||
id(new PHUIListItemView())
|
||||
->setName(pht('Ask Question'))
|
||||
->setHref($href)
|
||||
->setIcon('fa-plus-square'));
|
||||
id(new PonderQuestionEditEngine())
|
||||
->setViewer($this->getViewer())
|
||||
->addActionToCrumbs($crumbs);
|
||||
|
||||
return $crumbs;
|
||||
}
|
||||
|
|
|
@ -1,222 +1,11 @@
|
|||
<?php
|
||||
|
||||
final class PonderQuestionEditController extends PonderController {
|
||||
|
||||
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_wiki = $question->getAnswerWiki();
|
||||
$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_wiki = $request->getStr('answerWiki');
|
||||
$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(PonderQuestionTitleTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue($v_title);
|
||||
|
||||
$xactions[] = id(clone $template)
|
||||
->setTransactionType(
|
||||
PonderQuestionContentTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue($v_content);
|
||||
|
||||
$xactions[] = id(clone $template)
|
||||
->setTransactionType(
|
||||
PonderQuestionAnswerWikiTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue($v_wiki);
|
||||
|
||||
if (!$is_new) {
|
||||
$xactions[] = id(clone $template)
|
||||
->setTransactionType(
|
||||
PonderQuestionStatusTransaction::TRANSACTIONTYPE)
|
||||
->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('Question Details'))
|
||||
->setUser($viewer))
|
||||
->appendChild(
|
||||
id(new PhabricatorRemarkupControl())
|
||||
->setUser($viewer)
|
||||
->setName('answerWiki')
|
||||
->setID('answerWiki')
|
||||
->setValue($v_wiki)
|
||||
->setLabel(pht('Answer Summary'))
|
||||
->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('Tags'))
|
||||
->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/'));
|
||||
|
||||
$answer_preview = id(new PHUIRemarkupPreviewPanel())
|
||||
->setHeader(pht('Answer Summary Preview'))
|
||||
->setControlID('answerWiki')
|
||||
->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');
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($title)
|
||||
->setHeaderIcon('fa-pencil');
|
||||
} else {
|
||||
$crumbs->addTextCrumb(pht('Ask Question'));
|
||||
$title = pht('Ask New Question');
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($title)
|
||||
->setHeaderIcon('fa-plus-square');
|
||||
}
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
$box = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Question'))
|
||||
->setFormErrors($errors)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setForm($form);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(array(
|
||||
$box,
|
||||
$preview,
|
||||
$answer_preview,
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($view);
|
||||
|
||||
return id(new PonderQuestionEditEngine())
|
||||
->setController($this)
|
||||
->buildResponse();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,14 @@ final class PonderAnswerEditor extends PonderEditor {
|
|||
return pht('Ponder Answers');
|
||||
}
|
||||
|
||||
public function getCreateObjectTitle($author, $object) {
|
||||
return pht('%s added this answer.', $author);
|
||||
}
|
||||
|
||||
public function getCreateObjectTitleForFeed($author, $object) {
|
||||
return pht('%s added %s.', $author, $object);
|
||||
}
|
||||
|
||||
public function getTransactionTypes() {
|
||||
$types = parent::getTransactionTypes();
|
||||
$types[] = PhabricatorTransactions::TYPE_COMMENT;
|
||||
|
|
109
src/applications/ponder/editor/PonderQuestionEditEngine.php
Normal file
109
src/applications/ponder/editor/PonderQuestionEditEngine.php
Normal file
|
@ -0,0 +1,109 @@
|
|||
<?php
|
||||
|
||||
final class PonderQuestionEditEngine
|
||||
extends PhabricatorEditEngine {
|
||||
|
||||
const ENGINECONST = 'ponder.question';
|
||||
|
||||
public function getEngineName() {
|
||||
return pht('Ponder Question');
|
||||
}
|
||||
|
||||
public function getEngineApplicationClass() {
|
||||
return 'PhabricatorPonderApplication';
|
||||
}
|
||||
|
||||
public function getSummaryHeader() {
|
||||
return pht('Configure Ponder Question Forms');
|
||||
}
|
||||
|
||||
public function getSummaryText() {
|
||||
return pht('Configure creation and editing forms in Ponder Questions.');
|
||||
}
|
||||
|
||||
public function isEngineConfigurable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function newEditableObject() {
|
||||
return PonderQuestion::initializeNewQuestion($this->getViewer());
|
||||
}
|
||||
|
||||
protected function newObjectQuery() {
|
||||
return new PonderQuestionQuery();
|
||||
}
|
||||
|
||||
protected function getObjectCreateTitleText($object) {
|
||||
return pht('Create New Question');
|
||||
}
|
||||
|
||||
protected function getObjectEditTitleText($object) {
|
||||
return pht('Edit Question: %s', $object->getTitle());
|
||||
}
|
||||
|
||||
protected function getObjectEditShortText($object) {
|
||||
return $object->getTitle();
|
||||
}
|
||||
|
||||
protected function getObjectCreateShortText() {
|
||||
return pht('New Question');
|
||||
}
|
||||
|
||||
protected function getObjectName() {
|
||||
return pht('Question');
|
||||
}
|
||||
|
||||
protected function getObjectCreateCancelURI($object) {
|
||||
return $this->getApplication()->getApplicationURI('/');
|
||||
}
|
||||
|
||||
protected function getEditorURI() {
|
||||
return $this->getApplication()->getApplicationURI('question/edit/');
|
||||
}
|
||||
|
||||
protected function getObjectViewURI($object) {
|
||||
return $object->getViewURI();
|
||||
}
|
||||
|
||||
protected function buildCustomEditFields($object) {
|
||||
|
||||
return array(
|
||||
id(new PhabricatorTextEditField())
|
||||
->setKey('title')
|
||||
->setLabel(pht('Question'))
|
||||
->setDescription(pht('Question title.'))
|
||||
->setConduitTypeDescription(pht('New question title.'))
|
||||
->setTransactionType(
|
||||
PonderQuestionTitleTransaction::TRANSACTIONTYPE)
|
||||
->setValue($object->getTitle())
|
||||
->setIsRequired(true),
|
||||
id(new PhabricatorRemarkupEditField())
|
||||
->setKey('content')
|
||||
->setLabel(pht('Details'))
|
||||
->setDescription(pht('Long details of the question.'))
|
||||
->setConduitTypeDescription(pht('New question details.'))
|
||||
->setValue($object->getContent())
|
||||
->setTransactionType(
|
||||
PonderQuestionContentTransaction::TRANSACTIONTYPE),
|
||||
id(new PhabricatorRemarkupEditField())
|
||||
->setKey('answerWiki')
|
||||
->setLabel(pht('Answer Summary'))
|
||||
->setDescription(pht('Answer summary of the question.'))
|
||||
->setConduitTypeDescription(pht('New question answer summary.'))
|
||||
->setValue($object->getAnswerWiki())
|
||||
->setTransactionType(
|
||||
PonderQuestionAnswerWikiTransaction::TRANSACTIONTYPE),
|
||||
id(new PhabricatorSelectEditField())
|
||||
->setKey('status')
|
||||
->setLabel(pht('Status'))
|
||||
->setDescription(pht('Status of the question.'))
|
||||
->setConduitTypeDescription(pht('New question status.'))
|
||||
->setValue($object->getStatus())
|
||||
->setTransactionType(
|
||||
PonderQuestionStatusTransaction::TRANSACTIONTYPE)
|
||||
->setOptions(PonderQuestionStatus::getQuestionStatusMap()),
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -9,6 +9,14 @@ final class PonderQuestionEditor
|
|||
return pht('Ponder Questions');
|
||||
}
|
||||
|
||||
public function getCreateObjectTitle($author, $object) {
|
||||
return pht('%s created this question.', $author);
|
||||
}
|
||||
|
||||
public function getCreateObjectTitleForFeed($author, $object) {
|
||||
return pht('%s created %s.', $author, $object);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used internally on @{method:applyInitialEffects} if a transaction
|
||||
* of type PonderQuestionTransaction::TYPE_ANSWERS is in the mix. The value
|
||||
|
@ -64,11 +72,8 @@ final class PonderQuestionEditor
|
|||
|
||||
public function getTransactionTypes() {
|
||||
$types = parent::getTransactionTypes();
|
||||
|
||||
$types[] = PhabricatorTransactions::TYPE_COMMENT;
|
||||
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
|
||||
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
|
||||
$types[] = PhabricatorTransactions::TYPE_SPACE;
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
|
|
@ -105,6 +105,14 @@ final class PonderQuestion extends PonderDAO
|
|||
return $this->comments;
|
||||
}
|
||||
|
||||
public function getMonogram() {
|
||||
return 'Q'.$this->getID();
|
||||
}
|
||||
|
||||
public function getViewURI() {
|
||||
return '/'.$this->getMonogram();
|
||||
}
|
||||
|
||||
public function attachAnswers(array $answers) {
|
||||
assert_instances_of($answers, 'PonderAnswer');
|
||||
$this->answers = $answers;
|
||||
|
|
|
@ -21,6 +21,13 @@ final class PonderQuestionAnswerTransaction
|
|||
$this->renderAuthor());
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
return pht(
|
||||
'%s added an answer to %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderObject());
|
||||
}
|
||||
|
||||
public function getIcon() {
|
||||
return 'fa-plus';
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue