]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Work on QnA notice display -- in progress
authorZach Copley <zach@status.net>
Tue, 22 Mar 2011 03:57:19 +0000 (20:57 -0700)
committerZach Copley <zach@status.net>
Tue, 22 Mar 2011 03:57:19 +0000 (20:57 -0700)
plugins/QnA/QnAPlugin.php
plugins/QnA/actions/qnashowanswer.php
plugins/QnA/actions/qnashowquestion.php
plugins/QnA/actions/qnavote.php
plugins/QnA/classes/QnA_Answer.php
plugins/QnA/classes/QnA_Question.php
plugins/QnA/lib/qnaansweredform.php [new file with mode: 0644]

index ba3b6e329a8bb9717c518d6238ce9b5821036391..992641b18e13684be5f888eda972e697a8e68041 100644 (file)
@@ -88,7 +88,8 @@ class QnAPlugin extends MicroAppPlugin
             return false;
         case 'QnaquestionForm':
         case 'QnaanswerForm':
-        case 'QnavoteForm';
+        case 'QnaansweredForm':
+        case 'QnavoteForm':
             include_once $dir . '/lib/' . strtolower($cls).'.php';
             break;
         case 'QnA_Question':
@@ -201,24 +202,23 @@ class QnAPlugin extends MicroAppPlugin
 
         switch ($activity->verb) {
         case ActivityVerb::POST:
-            $notice = Question::saveNew(
+            $notice = QnA_Question::saveNew(
                 $actor,
-                $questionObj->title
-               // null,
-               // $questionObj->summary,
-               // $options
+                $questionObj->title,
+                $questionObj->summary,
+                $options
             );
             break;
-        case Answer::NORMAL:
+        case Answer::ObjectType:
             $question = QnA_Question::staticGet('uri', $questionObj->id);
             if (empty($question)) {
                 // FIXME: save the question
                 throw new Exception("Answer to unknown question.");
             }
-            $notice = QnA_Answer::saveNew($actor, $question, $activity->verb, $options);
+            $notice = QnA_Answer::saveNew($actor, $question, $options);
             break;
         default:
-            throw new Exception("Unknown verb for question");
+            throw new Exception("Unknown object type received by QnA Plugin");
         }
 
         return $notice;
@@ -292,127 +292,67 @@ class QnAPlugin extends MicroAppPlugin
      * @param Notice $notice
      * @param HTMLOutputter $out
      */
-
     function showNotice($notice, $out)
     {
         switch ($notice->object_type) {
         case QnA_Question::OBJECT_TYPE:
-            $this->showQuestionNotice($notice, $out);
-            break;
+            return $this->showNoticeQuestion($notice, $out);
         case QnA_Answer::OBJECT_TYPE:
-            $this->showAnswerNotice($notice, $out);
-            break;
+            return $this->showNoticeAnswer($notice, $out);
+        default:
+            // TRANS: Exception thrown when performing an unexpected action on a question.
+            // TRANS: %s is the unpexpected object type.
+            throw new Exception(
+                sprintf(
+                    _m('Unexpected type for QnA plugin: %s.'), 
+                    $notice->object_type
+                )
+            );
         }
-
-        // bad craziness
-        $out->elementStart('div', array('class' => 'question'));
-
-        $profile = $notice->getProfile();
-        $avatar = $profile->getAvatar(AVATAR_MINI_SIZE);
-
-        $out->element(
-            'img',
-            array(
-                'src'    => ($avatar)
-                    ? $avatar->displayUrl()
-                    : Avatar::defaultImage(AVATAR_MINI_SIZE),
-                'class'  => 'avatar photo question-avatar',
-                'width'  => AVATAR_MINI_SIZE,
-                'height' => AVATAR_MINI_SIZE,
-                'alt'    => $profile->getBestName()
-            )
-        );
-
-        $out->raw('&#160;'); // avoid &nbsp; for AJAX XML compatibility
-
-        // hack for belongsOnTimeline; JS needs to be able to find the author
-        $out->elementStart('span', 'vcard author');
-        $out->element(
-            'a',
-            array(
-                'class' => 'url',
-                'href'  => $profile->profileurl,
-                'title' => $profile->getBestName()
-            ),
-            $profile->nickname
-        );
-
-        $out->elementEnd('span');
     }
-
-    function showAnswerNotice($notice, $out)
+    
+    function showNoticeQuestion($notice, $out)
     {
-        $answer = QnA_Answer::fromNotice($notice);
-
-        assert(!empty($answer));
-
-        $out->elementStart('div', 'answer');
-        $out->raw($answer->asHTML());
-        $out->elementEnd('div');
-    }
-
-    function showQuestionNotice($notice, $out)
-    {
-        $profile  = $notice->getProfile();
-        $question = QnA_Question::fromNotice($notice);
-
-        assert(!empty($question));
-        assert(!empty($profile));
-
-        $out->elementStart('div', 'question-notice');
-
-        $out->elementStart('h3');
+        $user = common_current_user();
 
-        if (!empty($question->url)) {
-            $out->element(
-                'a',
-                array(
-                    'href'  => $question->url,
-                    'class' => 'question-title'
-                ),
-                $question->title
-            );
+        // @hack we want regular rendering, then just add stuff after that
+        $nli = new NoticeListItem($notice, $out);
+        $nli->showNotice();
+
+        $out->elementStart('div', array('class' => 'entry-content question-content'));
+        $question = QnA_Question::getByNotice($notice);
+        
+        if ($question) {
+            if ($user) {
+                $profile = $user->getProfile();
+                $answer = $question->getAnswer($profile);
+                if ($answer) {
+                    // User has already answer; show the results.
+                    $form = new QnaansweredForm($answer, $out);
+                } else {
+                    $form = new QnaanswerForm($question, $out);
+                }
+                $form->show();
+            }
         } else {
-            $out->text($question->title);
+            $out->text(_m('Question data is missing'));
         }
-
-        if (!empty($question->location)) {
-            $out->elementStart('div', 'question-location');
-            $out->element('strong', null, _('Location: '));
-            $out->element('span', 'location', $question->location);
-            $out->elementEnd('div');
-        }
-
-        if (!empty($question->description)) {
-            $out->elementStart('div', 'question-description');
-            $out->element('strong', null, _('Description: '));
-            $out->element('span', 'description', $question->description);
-            $out->elementEnd('div');
-        }
-
-        //$answers = $question->getAnswers();
-
-        $out->elementStart('div', 'question-answers');
-        $out->element('strong', null, _('Answer: '));
-        $out->element('span', 'question-answer');
-
         $out->elementEnd('div');
 
-        $user = common_current_user();
-
-        if (!empty($user)) {
-
-            $answer = $question->getAnswer($user->getProfile());
-
-            if (empty($answer)) {
-                $form = new QnaanswerForm($question, $out);
-                $form->show();
-            }
+        // @fixme
+        $out->elementStart('div', array('class' => 'entry-content'));
+    }
 
+    function showNoticeAnswer($notice, $out)
+    {
+        $user = common_current_user();
 
-        }
+        // @hack we want regular rendering, then just add stuff after that
+        $nli = new NoticeListItem($notice, $out);
+        $nli->showNotice();
 
-        $out->elementEnd('div');
+        // @fixme
+        $out->elementStart('div', array('class' => 'entry-content'));
     }
 
     /**
index 68baadfba81c6a1d3597adfc62835775d267b733..9721f22da343dec32ee6623a50cdafe078f6fe1e 100644 (file)
@@ -63,7 +63,7 @@ class QnashowanswerAction extends ShownoticeAction
 
         $this->id = $this->trimmed('id');
 
-        $this->answer = Answer::staticGet('id', $this->id);
+        $this->answer = QnA_Answer::staticGet('id', $this->id);
 
         if (empty($this->answer)) {
             throw new ClientException(_('No such answer.'), 404);
@@ -117,9 +117,11 @@ class QnashowanswerAction extends ShownoticeAction
     function showPageTitle()
     {
         $this->elementStart('h1');
-        $this->element('a',
-                       array('href' => $this->answer->url),
-                       $this->asnwer->title);
+        $this->element(
+            'a',
+            array('href' => $this->answer->url),
+            $this->answer->title
+        );
         $this->elementEnd('h1');
     }
 }
index e563753a01402de2598f0033cedacef166454245..671912535407a1822bca4b9a3c4e1706bbe45710 100644 (file)
@@ -61,7 +61,7 @@ class QnashowquestionAction extends ShownoticeAction
 
         $this->id = $this->trimmed('id');
 
-        $this->question = Question::staticGet('id', $this->id);
+        $this->question = QnA_Question::staticGet('id', $this->id);
 
         if (empty($this->question)) {
             // TRANS: Client exception thrown trying to view a non-existing question.
@@ -108,7 +108,7 @@ class QnashowquestionAction extends ShownoticeAction
         // TRANS: %1$s is the nickname of the user who asked the question, %2$s is the question.
         return sprintf(_m('%1$s\'s question: %2$s'),
                        $this->user->nickname,
-                       $this->question->question);
+                       $this->question->title);
     }
 
     /**
index 94aec41c5be5b6cb0cfdc9a3a2051d4a0f6d99f2..8098cb87d0d97ae1542498e594204edb8478447d 100644 (file)
@@ -90,7 +90,7 @@ class Qnavote extends Action
         }
 
         $id = $this->trimmed('id');
-        $this->question = Question::staticGet('id', $id);
+        $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);
index ff11ff8f141a55111164236d2902ed88dfd9dec2..57c08afe4ed22c07a2e38e46ac26fdedc8ed54e8 100644 (file)
@@ -50,7 +50,9 @@ class QnA_Answer extends Managed_DataObject
     public $id;          // char(36) primary key not null -> UUID
     public $question_id; // char(36) -> question.id UUID
     public $profile_id;  // int -> question.id
-    public $best;        // (int) boolean -> whether the question asker has marked this as the best answer
+    public $best;        // (boolean) int -> whether the question asker has marked this as the best answer
+    public $revisions;   // int -> count of revisions to this answer
+    public $text;        // text -> response text
     public $created;     // datetime
 
     /**
@@ -105,14 +107,15 @@ class QnA_Answer extends Managed_DataObject
                         'description' => 'UUID to the answer notice'
                     ),
                     'question_id' => array(
-                        'type'     => 'char',
-                        'length'   => 36,
-                        'not null' => true,
+                        'type'        => 'char',
+                        'length'      => 36,
+                        'not null'    => true,
                         'description' => 'UUID of question being responded to'
                     ),
-                    'best'     => array('type' => 'int', 'size' => 'tiny'),
-                    'profile_id'  => array('type' => 'int'),
-                    'created'     => array('type' => 'datetime', 'not null' => true),
+                    'best'       => array('type' => 'int', 'size' => 'tiny'),
+                    'revisions'  => array('type' => 'int'),
+                    'profile_id' => array('type' => 'int'),
+                    'created'    => array('type' => 'datetime', 'not null' => true),
             ),
             'primary key' => array('id'),
             'unique keys' => array(
@@ -134,7 +137,11 @@ class QnA_Answer extends Managed_DataObject
      */
     function getByNotice($notice)
     {
-        return self::staticGet('uri', $notice->uri);
+        $answer = self::staticGet('uri', $notice->uri);
+        if (empty($answer)) {
+            throw new Exception("No answer with URI {$this->notice->uri}");
+        }
+        return $answer;
     }
 
     /**
@@ -159,14 +166,93 @@ class QnA_Answer extends Managed_DataObject
      */
     function getQuestion()
     {
-        return Question::staticGet('id', $this->question_id);
+        $question = self::staticGet('id', $this->question_id);
+        if (empty($question)) {
+            throw new Exception("No question with ID {$this->question_id}");
+        }
+        return question;
+    }
+    
+    function getProfile()
+    {
+        $profile = Profile::staticGet('id', $this->profile_id);
+        if (empty($profile)) {
+            throw new Exception("No profile with ID {$this->profile_id}");
+        }
+        return $profile;
     }
 
-    static function fromNotice($notice)
+    function asHTML()
     {
-        return self::staticGet('uri', $notice->uri);
+        return self::toHTML(
+            $this->getProfile(),
+            $this->getQuestion()
+        );
     }
 
+    function asString()
+    {
+        return self::toString(
+            $this->getProfile(),
+            $this->getQuestion()
+        );
+    }
+
+    static function toHTML($profile, $event, $response)
+    {
+        $fmt = null;
+
+        $notice = $event->getNotice();
+
+        switch ($response) {
+        case 'Y':
+            $fmt = _("<span class='automatic event-rsvp'><a href='%1s'>%2s</a> is attending <a href='%3s'>%4s</a>.</span>");
+            break;
+        case 'N':
+            $fmt = _("<span class='automatic event-rsvp'><a href='%1s'>%2s</a> is not attending <a href='%3s'>%4s</a>.</span>");
+            break;
+        case '?':
+            $fmt = _("<span class='automatic event-rsvp'><a href='%1s'>%2s</a> might attend <a href='%3s'>%4s</a>.</span>");
+            break;
+        default:
+            throw new Exception("Unknown response code {$response}");
+            break;
+        }
+
+        return sprintf($fmt,
+                       htmlspecialchars($profile->profileurl),
+                       htmlspecialchars($profile->getBestName()),
+                       htmlspecialchars($notice->bestUrl()),
+                       htmlspecialchars($event->title));
+    }
+
+    static function toString($profile, $event, $response)
+    {
+        $fmt = null;
+
+        $notice = $event->getNotice();
+
+        switch ($response) {
+        case 'Y':
+            $fmt = _("%1s is attending %2s.");
+            break;
+        case 'N':
+            $fmt = _("%1s is not attending %2s.");
+            break;
+        case '?':
+            $fmt = _("%1s might attend %2s.>");
+            break;
+        default:
+            throw new Exception("Unknown response code {$response}");
+            break;
+        }
+
+        return sprintf($fmt,
+                       $profile->getBestName(),
+                       $event->title);
+    }
+
+
     /**
      * Save a new answer notice
      *
@@ -176,7 +262,7 @@ class QnA_Answer extends Managed_DataObject
      *
      * @return Notice saved notice
      */
-    static function saveNew($profile, $question, $options = null)
+    static function saveNew($profile, $question, $text, $options = null)
     {
         if (empty($options)) {
             $options = array();
@@ -186,23 +272,24 @@ class QnA_Answer extends Managed_DataObject
         $answer->id          = UUID::gen();
         $answer->profile_id  = $profile->id;
         $answer->question_id = $question->id;
+        $answer->revisions   = 0;
+        $answer->best        = 0;
+        $answer->text        = $text;
         $answer->created     = common_sql_now();
         $answer->uri         = common_local_url(
-            'showanswer',
+            'qnashowanswer',
             array('id' => $answer->id)
         );
 
         common_log(LOG_DEBUG, "Saving answer: $answer->id, $answer->uri");
         $answer->insert();
 
-        // TRANS: Notice content answering a question.
-        // TRANS: %s is the answer
         $content  = sprintf(
             _m('answered "%s"'),
-            $answer->uri
+            $question->title
         );
 
-        $link = '<a href="' . htmlspecialchars($answer->uri) . '">' . htmlspecialchars($answer) . '</a>';
+        $link = '<a href="' . htmlspecialchars($answer->uri) . '">' . htmlspecialchars($question->title) . '</a>';
         // TRANS: Rendered version of the notice content answering a question.
         // TRANS: %s a link to the question with question title as the link content.
         $rendered = sprintf(_m('answered "%s"'), $link);
@@ -213,13 +300,15 @@ class QnA_Answer extends Managed_DataObject
         $options = array_merge(
             array(
                 'urls'        => array(),
+                'content'     => $content,
                 'rendered'    => $rendered,
                 'tags'        => $tags,
                 'replies'     => $replies,
                 'reply_to'    => $question->getNotice()->id,
-                'object_type' => self::OBJECT_TYPE),
-                $options
-            );
+                'object_type' => self::OBJECT_TYPE
+            ),
+            $options
+        );
 
         if (!array_key_exists('uri', $options)) {
             $options['uri'] = $answer->uri;
index 308e87b99f744b2d0ddfe6f46310149d22670588..523092359097740b76231318e5aef7ecaf103124 100644 (file)
@@ -113,7 +113,7 @@ class QnA_Question extends Managed_DataObject
                 'closed'      => array('type' => 'int', 'size' => 'tiny'),
                 'description' => array('type' => 'text'),
                 'created'     => array(
-                    'type' => 'datetime',
+                    'type'     => 'datetime',
                     'not null' => true
                 ),
             ),
@@ -175,7 +175,6 @@ class QnA_Question extends Managed_DataObject
 
     static function fromNotice($notice)
     {
-        common_debug('xxxxxxxxxxxxxxx notice-uri = ' . $notice->uri);
         return QnA_Question::staticGet('uri', $notice->uri);
     }
 
@@ -209,7 +208,7 @@ class QnA_Question extends Managed_DataObject
             $q->uri = $options['uri'];
         } else {
             $q->uri = common_local_url(
-                'showquestion',
+                'qnashowquestion',
                 array('id' => $q->id)
             );
         }
diff --git a/plugins/QnA/lib/qnaansweredform.php b/plugins/QnA/lib/qnaansweredform.php
new file mode 100644 (file)
index 0000000..a229e7f
--- /dev/null
@@ -0,0 +1,122 @@
+<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2011, StatusNet, Inc.
+ *
+ * Form for answering a question
+ *
+ * PHP version 5
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category  QnA
+ * @package   StatusNet
+ * @author    Zach Copley <zach@status.net>
+ * @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 answer to a question
+ *
+ * @category  QnA
+ * @package   StatusNet
+ * @author    Zach Copley <zach@status.net>
+ * @copyright 2011 StatusNet, Inc.
+ * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link      http://status.net/
+ */
+class QnaansweredForm extends Form
+{
+    protected $question;
+    protected $answer;
+
+    /**
+     * Construct a new answer form
+     *
+     * @param QnA_Answer $answer
+     * @param HTMLOutputter $out output channel
+     *
+     * @return void
+     */
+    function __construct(QnA_Answer $answer, HTMLOutputter $out)
+    {
+        parent::__construct($out);
+        $this->question = $answer->getQuestion(); 
+        $this->answer   = $answer;
+    }
+
+    /**
+     * ID of the form
+     *
+     * @return int ID of the form
+     */
+    function id()
+    {
+        return 'answered-form';
+    }
+
+    /**
+     * class of the form
+     *
+     * @return string class of the form
+     */
+    function formClass()
+    {
+        return 'form_settings ajax';
+    }
+
+    /**
+     * Action of the form
+     *
+     * @return string URL of the action
+     */
+    function action()
+    {
+        return common_local_url('qnareviseanswer', array('id' => $this->question->id));
+    }
+
+    /**
+     * Data elements of the form
+     *
+     * @return void
+     */
+    function formData()
+    {
+        $question = $this->question;
+        $out      = $this->out;
+        $id       = "question-" . $question->id;
+
+        $out->element('p', 'Your answer to:', $question->title);
+        $out->element('input', array('type' => 'text', 'name' => 'answer'));
+    }
+
+    /**
+     * Action elements
+     *
+     * @return void
+     */
+    function formActions()
+    {
+        // TRANS: Button text for submitting a poll response.
+        $this->out->submit('submit', _m('BUTTON', 'Submit'));
+    }
+}