From: Zach Copley Date: Mon, 4 Apr 2011 21:33:20 +0000 (-0700) Subject: QnA - Allow closing questions X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=5193afb8bf304071f4af79f165bc27c66ee33d7e;p=quix0rs-gnu-social.git QnA - Allow closing questions --- diff --git a/plugins/QnA/QnAPlugin.php b/plugins/QnA/QnAPlugin.php index a586d89b40..cc70cb7aeb 100644 --- a/plugins/QnA/QnAPlugin.php +++ b/plugins/QnA/QnAPlugin.php @@ -81,18 +81,19 @@ class QnAPlugin extends MicroAppPlugin case 'QnanewquestionAction': case 'QnanewanswerAction': case 'QnashowquestionAction': + case 'QnaclosequestionAction': case 'QnashowanswerAction': case 'QnareviseanswerAction': case 'QnavoteAction': include_once $dir . '/actions/' . strtolower(mb_substr($cls, 0, -6)) . '.php'; return false; - case 'QnaquestionForm': - case 'QnashowanswerForm': + case 'QnanewquestionForm': + case 'QnashowquestionForm': case 'QnanewanswerForm': + case 'QnashowanswerForm': case 'QnareviseanswerForm': case 'QnavoteForm': - case 'AnswerNoticeListItem': include_once $dir . '/lib/' . strtolower($cls).'.php'; break; case 'QnA_Question': @@ -122,6 +123,10 @@ class QnAPlugin extends MicroAppPlugin 'main/qna/newquestion', array('action' => 'qnanewquestion') ); + $m->connect( + 'answer/qna/closequestion', + array('action' => 'qnaclosequestion') + ); $m->connect( 'main/qna/newanswer', array('action' => 'qnanewanswer') @@ -384,23 +389,19 @@ class QnAPlugin extends MicroAppPlugin $question = QnA_Question::getByNotice($notice); if (!empty($question)) { - - $short = $this->shorten($question->description, $notice); - $out->raw($short); - - // Don't prompt user for an answer if the question is closed or - // the current user posed the question in the first place - if (empty($question->closed)) { - if (!empty($user)) { - $profile = $user->getProfile(); - $answer = $question->getAnswer($profile); - if (!$answer) { - $form = new QnanewanswerForm($question, $out); - $form->show(); - } - } + if (empty($user)) { + $form = new QnashowquestionForm($out, $question); + $form->show(); } else { - $out->element('span', 'closed', _m('This question is closed.')); + $profile = $user->getProfile(); + $answer = $question->getAnswer($profile); + if (empty($answer)) { + $form = new QnanewanswerForm($out, $question); + $form->show(); + } else { + $form = new QnashowquestionForm($out, $question); + $form->show(); + } } } else { $out->text(_m('Question data is missing.')); @@ -465,7 +466,7 @@ class QnAPlugin extends MicroAppPlugin function entryForm($out) { - return new QnaquestionForm($out); + return new QnanewquestionForm($out); } /** diff --git a/plugins/QnA/actions/qnaclosequestion.php b/plugins/QnA/actions/qnaclosequestion.php new file mode 100644 index 0000000000..28d4e547b4 --- /dev/null +++ b/plugins/QnA/actions/qnaclosequestion.php @@ -0,0 +1,200 @@ +. + * + * @category QnA + * @package StatusNet + * @author Zach Copley + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Close a question to new answers + * + * @category QnA + * @package StatusNet + * @author Zach Copley + * @copyright 2010 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ +class QnaclosequestionAction extends Action +{ + protected $user = null; + protected $error = null; + protected $complete = null; + + protected $question = null; + protected $answer = null; + + /** + * Returns the title of the action + * + * @return string Action title + */ + function title() + { + // TRANS: Page title for close a question + return _m('Close question'); + } + + /** + * For initializing members of the class. + * + * @param array $argarray misc. arguments + * + * @return boolean true + */ + function prepare($argarray) + { + parent::prepare($argarray); + if ($this->boolean('ajax')) { + StatusNet::setApi(true); + } + + $this->user = common_current_user(); + + if (empty($this->user)) { + // TRANS: Client exception thrown trying to close a question when not logged in + throw new ClientException( + _m("You must be logged in to close a question."), + 403 + ); + } + + if ($this->isPost()) { + $this->checkSessionToken(); + } + + $id = substr($this->trimmed('id'), 9); + $this->question = QnA_Question::staticGet('id', $id); + if (empty($this->question)) { + // TRANS: Client exception thrown trying to respond to a non-existing question. + throw new ClientException(_m('Invalid or missing question.'), 404); + } + + return true; + } + + /** + * Handler method + * + * @param array $argarray is ignored since it's now passed in in prepare() + * + * @return void + */ + function handle($argarray=null) + { + parent::handle($argarray); + + if ($this->isPost()) { + $this->closeQuestion(); + } else { + $this->showPage(); + } + + return; + } + + /** + * Close a question + * + * @return void + */ + function closeQuestion() + { + + $user = common_current_user(); + + try { + + if ($user->id != $this->question->profile_id) { + throw new Exception(_m('You didn\'t ask this question.')); + } + + $orig = clone($this->question); + $this->question->closed = 1; + $this->question->update($orig); + + } catch (ClientException $ce) { + $this->error = $ce->getMessage(); + $this->showPage(); + return; + } + + if ($this->boolean('ajax')) { + header('Content-Type: text/xml;charset=utf-8'); + $this->xw->startDocument('1.0', 'UTF-8'); + $this->elementStart('html'); + $this->elementStart('head'); + // TRANS: Page title after sending an answer. + $this->element('title', null, _m('Answers')); + $this->elementEnd('head'); + $this->elementStart('body'); + $form = new QnashowquestionForm($this, $this->question); + $form->show(); + $this->elementEnd('body'); + $this->elementEnd('html'); + } else { + common_redirect($this->question->bestUrl(), 303); + } + } + + /** + * Show the close question form + * + * @return void + */ + function showContent() + { + if (!empty($this->error)) { + $this->element('p', 'error', $this->error); + } + + // blar + } + + /** + * Return true if read only. + * + * MAY override + * + * @param array $args other arguments + * + * @return boolean is read only action? + */ + function isReadOnly($args) + { + if ($_SERVER['REQUEST_METHOD'] == 'GET' || + $_SERVER['REQUEST_METHOD'] == 'HEAD') { + return true; + } else { + return false; + } + } +} diff --git a/plugins/QnA/classes/QnA_Question.php b/plugins/QnA/classes/QnA_Question.php index 0446128ea0..93d45c56c8 100644 --- a/plugins/QnA/classes/QnA_Question.php +++ b/plugins/QnA/classes/QnA_Question.php @@ -201,66 +201,31 @@ class QnA_Question extends Managed_DataObject function asHTML() { - return self::toHTML( - $this->getProfile(), - $this, - $this->getAnswers() - ); + return self::toHTML($this->getProfile(), $this); } function asString() { - return self::toString( - $this->getProfile(), - $this, - $this->getAnswers() - ); + return self::toString($this->getProfile(), $this); } - static function toHTML($profile, $question, $answer) + static function toHTML($profile, $question) { $notice = $question->getNotice(); - $fmt = '

'; - $fmt .= '%2$s'; - $fmt .= '%3$s'; - $fmt .= 'asked by %5$s'; - $fmt .= '

'; + $fmt = '%s'; $q = sprintf( $fmt, - htmlspecialchars($notice->bestUrl()), - htmlspecialchars($question->title), - htmlspecialchars($question->description), - htmlspecialchars($profile->profileurl), - htmlspecialchars($profile->getBestName()) + htmlspecialchars($question->description) ); - $ans = array(); - - $ans[] = '
'; - - while($answer->fetch()) { - $ans[] = $answer->asHTML(); - } - - $ans[] .= '
'; - - return $q . implode($ans); + return $q; } static function toString($profile, $question, $answers) { - $fmt = _m( - '%1$s asked the question "%2$s": %3$s' - ); - - return sprintf( - $fmt, - htmlspecialchars($profile->getBestName()), - htmlspecialchars($question->title), - htmlspecialchars($question->description) - ); + return sprintf(htmlspecialchars($question->description)); } /** diff --git a/plugins/QnA/lib/qnanewanswerform.php b/plugins/QnA/lib/qnanewanswerform.php index 34e73def0a..db4d1dfafc 100644 --- a/plugins/QnA/lib/qnanewanswerform.php +++ b/plugins/QnA/lib/qnanewanswerform.php @@ -56,7 +56,7 @@ class QnanewanswerForm extends Form * * @return void */ - function __construct(QnA_Question $question, HTMLOutputter $out) + function __construct(HTMLOutputter $out, QnA_Question $question) { parent::__construct($out); $this->question = $question; @@ -103,6 +103,8 @@ class QnanewanswerForm extends Form $out = $this->out; $id = "question-" . $question->id; + $out->raw($this->question->asHTML()); + $out->element('p', 'answer', 'Your answer'); $out->hidden('id', $id); $out->textarea('answer', 'answer'); diff --git a/plugins/QnA/lib/qnanewquestionform.php b/plugins/QnA/lib/qnanewquestionform.php new file mode 100644 index 0000000000..114e6199a1 --- /dev/null +++ b/plugins/QnA/lib/qnanewquestionform.php @@ -0,0 +1,137 @@ +. + * + * @category QnA + * @package StatusNet + * @author Zach Copley + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Form to add a new question + * + * @category QnA + * @package StatusNet + * @author Zach Copley + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ +class QnanewquestionForm extends Form +{ + protected $title; + protected $description; + + /** + * Construct a new question form + * + * @param HTMLOutputter $out output channel + * + * @return void + */ + function __construct($out = null, $title = null, $description = null, $options = null) + { + parent::__construct($out); + $this->title = $title; + $this->description = $description; + } + + /** + * ID of the form + * + * @return int ID of the form + */ + function id() + { + return 'newquestion-form'; + } + + /** + * class of the form + * + * @return string class of the form + */ + function formClass() + { + return 'form_settings ajax-notice'; + } + + /** + * Action of the form + * + * @return string URL of the action + */ + function action() + { + return common_local_url('qnanewquestion'); + } + + /** + * Data elements of the form + * + * @return void + */ + function formData() + { + $this->out->elementStart('fieldset', array('id' => 'newquestion-data')); + $this->out->elementStart('ul', 'form_data'); + + $this->li(); + $this->out->input( + 'title', + _m('Title'), + $this->title, + _m('Title of your question') + ); + $this->unli(); + $this->li(); + $this->out->textarea( + 'description', + _m('Description'), + $this->description, + _m('Your question in detail') + ); + $this->unli(); + + $this->out->elementEnd('ul'); + $this->out->elementEnd('fieldset'); + } + + /** + * Action elements + * + * @return void + */ + function formActions() + { + // TRANS: Button text for saving a new question. + $this->out->submit('submit', _m('BUTTON', 'Save')); + } +} diff --git a/plugins/QnA/lib/qnaquestionform.php b/plugins/QnA/lib/qnaquestionform.php deleted file mode 100644 index 9d0c2aad59..0000000000 --- a/plugins/QnA/lib/qnaquestionform.php +++ /dev/null @@ -1,137 +0,0 @@ -. - * - * @category QnA - * @package StatusNet - * @author Zach Copley - * @copyright 2011 StatusNet, Inc. - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 - * @link http://status.net/ - */ - -if (!defined('STATUSNET')) { - // This check helps protect against security problems; - // your code file can't be executed directly from the web. - exit(1); -} - -/** - * Form to add a new question - * - * @category QnA - * @package StatusNet - * @author Zach Copley - * @copyright 2011 StatusNet, Inc. - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 - * @link http://status.net/ - */ -class QnaquestionForm extends Form -{ - protected $title; - protected $description; - - /** - * Construct a new question form - * - * @param HTMLOutputter $out output channel - * - * @return void - */ - function __construct($out = null, $title = null, $description = null, $options = null) - { - parent::__construct($out); - $this->title = $title; - $this->description = $description; - } - - /** - * ID of the form - * - * @return int ID of the form - */ - function id() - { - return 'newquestion-form'; - } - - /** - * class of the form - * - * @return string class of the form - */ - function formClass() - { - return 'form_settings ajax-notice'; - } - - /** - * Action of the form - * - * @return string URL of the action - */ - function action() - { - return common_local_url('qnanewquestion'); - } - - /** - * Data elements of the form - * - * @return void - */ - function formData() - { - $this->out->elementStart('fieldset', array('id' => 'newquestion-data')); - $this->out->elementStart('ul', 'form_data'); - - $this->li(); - $this->out->input( - 'title', - _m('Title'), - $this->title, - _m('Title of your question') - ); - $this->unli(); - $this->li(); - $this->out->textarea( - 'description', - _m('Description'), - $this->description, - _m('Your question in detail') - ); - $this->unli(); - - $this->out->elementEnd('ul'); - $this->out->elementEnd('fieldset'); - } - - /** - * Action elements - * - * @return void - */ - function formActions() - { - // TRANS: Button text for saving a new question. - $this->out->submit('submit', _m('BUTTON', 'Save')); - } -} diff --git a/plugins/QnA/lib/qnashowanswerform.php b/plugins/QnA/lib/qnashowanswerform.php index 54f3f8fcac..5ec63e1096 100644 --- a/plugins/QnA/lib/qnashowanswerform.php +++ b/plugins/QnA/lib/qnashowanswerform.php @@ -65,8 +65,8 @@ class QnashowanswerForm extends Form { parent::__construct($out); - $this->answer = $answer; - $this->question = $answer->getQuestion(); + $this->answer = $answer; + $this->question = $answer->getQuestion(); } /** @@ -124,6 +124,7 @@ class QnashowanswerForm extends Form 'id', 'revise-' . $this->answer->id ); + $this->out->raw($this->answer->asHTML()); } @@ -141,7 +142,6 @@ class QnashowanswerForm extends Form if (empty($this->question->closed)) { if ($user->id == $this->question->profile_id) { - common_debug("I am the question asker!"); if (empty($this->answer->best)) { $this->out->submit( 'best', diff --git a/plugins/QnA/lib/qnashowquestionform.php b/plugins/QnA/lib/qnashowquestionform.php new file mode 100644 index 0000000000..71e644e2dc --- /dev/null +++ b/plugins/QnA/lib/qnashowquestionform.php @@ -0,0 +1,160 @@ +. + * + * @category Form + * @package StatusNet + * @author Zach Copley + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + exit(1); +} + +require_once INSTALLDIR . '/lib/form.php'; + +/** + * Form for showing a question + * + * @category Form + * @package StatusNet + * @author Zach Copley + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + * + */ +class QnashowquestionForm extends Form +{ + /** + * The question to show + */ + var $question = null; + + /** + * Constructor + * + * @param HTMLOutputter $out output channel + * @param QnA_Question $question the question to show + */ + function __construct($out = null, $question = null) + { + parent::__construct($out); + $this->question = $question; + } + + /** + * ID of the form + * + * @return int ID of the form + */ + function id() + { + return 'question-' . $this->question->id; + } + + /** + * Action of the form + * + * @return string URL of the action + */ + function action() + { + return common_local_url('qnaclosequestion'); + } + + /** + * Include a session token for CSRF protection + * + * @return void + */ + function sessionToken() + { + $this->out->hidden( + 'token', + common_session_token() + ); + } + + /** + * Legend of the Form + * + * @return void + */ + function formLegend() + { + // TRANS: Form legend for revising the answer. + $this->out->element('legend', null, _('Question')); + } + + /** + * Data elements + * + * @return void + */ + function formData() + { + $this->out->hidden( + 'id', + 'question-' . $this->question->id + ); + + $this->out->raw($this->question->asHTML()); + } + + /** + * Action elements + * + * @return void + */ + function formActions() + { + $user = common_current_user(); + if (empty($user)) { + return; + } + + if (empty($this->question->closed)) { + if ($user->id == $this->question->profile_id) { + $this->out->submit( + 'close', + // TRANS: Button text for closing a question + _m('BUTTON', 'Close'), + 'submit', + null, + // TRANS: Title for button text for closing a question + _('Close the question') + ); + } + } + } + + /** + * Class of the form. + * + * @return string the form's class + */ + function formClass() + { + return 'form_close ajax'; + } +}