From e085ef5ef5c9f8f5a13877bce84bc094eb6a5a34 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Thu, 10 Mar 2011 12:38:25 -0800 Subject: [PATCH] Work on turning poll responses into activities so we can send them over ostatus bridge. Not yet bridging. --- plugins/Poll/Poll.php | 1 + plugins/Poll/PollPlugin.php | 35 ++++++++++- plugins/Poll/Poll_response.php | 112 ++++++++++++++++++++++++++++++++- plugins/Poll/respondpoll.php | 15 +++-- 4 files changed, 151 insertions(+), 12 deletions(-) diff --git a/plugins/Poll/Poll.php b/plugins/Poll/Poll.php index 65aad4830e..f5143c3e57 100644 --- a/plugins/Poll/Poll.php +++ b/plugins/Poll/Poll.php @@ -47,6 +47,7 @@ class Poll extends Managed_DataObject { public $__table = 'poll'; // table name public $id; // char(36) primary key not null -> UUID + public $uri; public $profile_id; // int -> profile.id public $question; // text public $options; // text; newline(?)-delimited diff --git a/plugins/Poll/PollPlugin.php b/plugins/Poll/PollPlugin.php index 8a69ccd225..be1dd58d59 100644 --- a/plugins/Poll/PollPlugin.php +++ b/plugins/Poll/PollPlugin.php @@ -47,7 +47,10 @@ if (!defined('STATUSNET')) { class PollPlugin extends MicroAppPlugin { const VERSION = '0.1'; - const POLL_OBJECT = 'http://apinamespace.org/activitystreams/object/poll'; + + // @fixme which domain should we use for these namespaces? + const POLL_OBJECT = 'http://apinamespace.org/activitystreams/object/poll'; + const POLL_RESPONSE_OBJECT = 'http://apinamespace.org/activitystreams/object/poll-response'; /** * Database schema setup @@ -130,6 +133,10 @@ class PollPlugin extends MicroAppPlugin array('action' => 'showpoll'), array('id' => '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}')); + $m->connect('main/poll/response/:id', + array('action' => 'showpollresponse'), + array('id' => '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}')); + $m->connect('main/poll/:id/respond', array('action' => 'respondpoll'), array('id' => '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}')); @@ -158,7 +165,7 @@ class PollPlugin extends MicroAppPlugin function types() { - return array(self::POLL_OBJECT); + return array(self::POLL_OBJECT, self::POLL_RESPONSE_OBJECT); } /** @@ -282,6 +289,18 @@ class PollPlugin extends MicroAppPlugin * and Bookmark plugin for if that's right. */ function showNotice($notice, $out) + { + switch ($notice->object_type) { + case self::POLL_OBJECT: + return $this->showNoticePoll($notice, $out); + case self::POLL_RESPONSE_OBJECT: + return $this->showNoticePollResponse($notice, $out); + default: + throw new Exception('Unexpected type for poll plugin: ' . $notice->object_type); + } + } + + function showNoticePoll($notice, $out) { $user = common_current_user(); @@ -312,6 +331,18 @@ class PollPlugin extends MicroAppPlugin $out->elementStart('div', array('class' => 'entry-content')); } + function showNoticePollResponse($notice, $out) + { + $user = common_current_user(); + + // @hack we want regular rendering, then just add stuff after that + $nli = new NoticeListItem($notice, $out); + $nli->showNotice(); + + // @fixme + $out->elementStart('div', array('class' => 'entry-content')); + } + function entryForm($out) { return new NewPollForm($out); diff --git a/plugins/Poll/Poll_response.php b/plugins/Poll/Poll_response.php index 44bc421c22..b5204c71f0 100644 --- a/plugins/Poll/Poll_response.php +++ b/plugins/Poll/Poll_response.php @@ -46,7 +46,8 @@ if (!defined('STATUSNET')) { class Poll_response extends Managed_DataObject { public $__table = 'poll_response'; // table name - public $poll_id; // char(36) primary key not null -> UUID + public $id; // char(36) primary key not null -> UUID + public $poll_id; // char(36) -> poll.id UUID public $profile_id; // int -> profile.id public $selection; // int -> choice # public $created; // datetime @@ -94,12 +95,16 @@ class Poll_response extends Managed_DataObject return array( 'description' => 'Record of responses to polls', 'fields' => array( - 'poll_id' => array('type' => 'char', 'length' => 36, 'not null' => true, 'description' => 'UUID'), + 'id' => array('type' => 'char', 'length' => 36, 'not null' => true, 'description' => 'UUID of the response'), + 'uri' => array('type' => 'varchar', 'length' => 255, 'not null' => true, 'description' => 'UUID to the response notice'), + 'poll_id' => array('type' => 'char', 'length' => 36, 'not null' => true, 'description' => 'UUID of poll being responded to'), 'profile_id' => array('type' => 'int'), 'selection' => array('type' => 'int'), 'created' => array('type' => 'datetime', 'not null' => true), ), + 'primary key' => array('id'), 'unique keys' => array( + 'poll_uri_key' => array('uri'), 'poll_response_poll_id_profile_id_key' => array('poll_id', 'profile_id'), ), 'indexes' => array( @@ -107,4 +112,107 @@ class Poll_response extends Managed_DataObject ) ); } + + /** + * Get a poll response based on a notice + * + * @param Notice $notice Notice to check for + * + * @return Poll_response found response or null + */ + + function getByNotice($notice) + { + return self::staticGet('uri', $notice->uri); + } + + /** + * Get the notice that belongs to this response... + * + * @return Notice + */ + function getNotice() + { + return Notice::staticGet('uri', $this->uri); + } + + function bestUrl() + { + return $this->getNotice()->bestUrl(); + } + + /** + * Save a new poll notice + * + * @param Profile $profile + * @param Poll $poll the poll being responded to + * @param int $selection (1-based) + * @param array $opts (poll responses) + * + * @return Notice saved notice + */ + + static function saveNew($profile, $poll, $selection, $options=null) + { + if (empty($options)) { + $options = array(); + } + + $opts = $poll->getOptions(); + if ($selection < 1 || $selection > count($opts)) { + throw new ClientException(_m('Invalid poll selection.')); + } + $answer = $opts[$selection - 1]; + + $pr = new Poll_response(); + $pr->id = UUID::gen(); + $pr->profile_id = $profile->id; + $pr->poll_id = $poll->id; + $pr->selection = $selection; + + if (array_key_exists('created', $options)) { + $pr->created = $options['created']; + } else { + $pr->created = common_sql_now(); + } + + if (array_key_exists('uri', $options)) { + $pr->uri = $options['uri']; + } else { + $pr->uri = common_local_url('showpollresponse', + array('id' => $pr->id)); + } + + common_log(LOG_DEBUG, "Saving poll response: $pr->id $pr->uri"); + $pr->insert(); + + $content = sprintf(_m('voted for "%s"'), + $answer); + $rendered = sprintf(_m('voted for “%s”'), + htmlspecialchars($poll->uri), + htmlspecialchars($answer)); + + $tags = array(); + $replies = array(); + + $options = array_merge(array('urls' => array(), + 'rendered' => $rendered, + 'tags' => $tags, + 'replies' => $replies, + 'reply_to' => $poll->getNotice()->id, + 'object_type' => PollPlugin::POLL_RESPONSE_OBJECT), + $options); + + if (!array_key_exists('uri', $options)) { + $options['uri'] = $pr->uri; + } + + $saved = Notice::saveNew($profile->id, + $content, + array_key_exists('source', $options) ? + $options['source'] : 'web', + $options); + + return $saved; + } } diff --git a/plugins/Poll/respondpoll.php b/plugins/Poll/respondpoll.php index 07a5235406..e521a2a68f 100644 --- a/plugins/Poll/respondpoll.php +++ b/plugins/Poll/respondpoll.php @@ -75,6 +75,9 @@ class RespondPollAction extends Action function prepare($argarray) { parent::prepare($argarray); + if ($this->boolean('ajax')) { + StatusNet::setApi(true); + } $this->user = common_current_user(); @@ -132,20 +135,16 @@ class RespondPollAction extends Action function respondPoll() { try { - $response = new Poll_response(); - $response->poll_id = $this->poll->id; - $response->profile_id = $this->user->id; - $response->selection = $this->selection; - $response->created = common_sql_now(); - $response->insert(); - + $notice = Poll_response::saveNew($this->user->getProfile(), + $this->poll, + $this->selection); } catch (ClientException $ce) { $this->error = $ce->getMessage(); $this->showPage(); return; } - if ($this->arg('ajax')) { + if ($this->boolean('ajax')) { header('Content-Type: text/xml;charset=utf-8'); $this->xw->startDocument('1.0', 'UTF-8'); $this->elementStart('html');