From d6c8c61076f744fbcf96f7edb5b50732515af04e Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Thu, 10 Mar 2011 13:41:23 -0800 Subject: [PATCH] AS output/input for poll responses --- plugins/Poll/Poll.php | 17 +++++++ plugins/Poll/PollPlugin.php | 84 +++++++++++++++++++++++++++++++--- plugins/Poll/Poll_response.php | 4 +- 3 files changed, 96 insertions(+), 9 deletions(-) diff --git a/plugins/Poll/Poll.php b/plugins/Poll/Poll.php index f5143c3e57..1f26bbf6e4 100644 --- a/plugins/Poll/Poll.php +++ b/plugins/Poll/Poll.php @@ -128,6 +128,23 @@ class Poll extends Managed_DataObject return explode("\n", $this->options); } + /** + * Is this a valid selection index? + * + * @param numeric $selection (1-based) + * @return boolean + */ + function isValidSelection($selection) + { + if ($selection != intval($selection)) { + return false; + } + if ($selection < 1 || $selection > count($this->getOptions())) { + return false; + } + return true; + } + function getNotice() { return Notice::staticGet('uri', $this->uri); diff --git a/plugins/Poll/PollPlugin.php b/plugins/Poll/PollPlugin.php index be1dd58d59..49f7011156 100644 --- a/plugins/Poll/PollPlugin.php +++ b/plugins/Poll/PollPlugin.php @@ -207,9 +207,10 @@ class PollPlugin extends MicroAppPlugin // Ok for now, we can grab stuff from the XML entry directly. // This won't work when reading from JSON source if ($activity->entry) { - $elements = $activity->entry->getElementsByTagNameNS(self::POLL_OBJECT, 'data'); - if ($elements->length) { - $data = $elements->item(0); + $pollElements = $activity->entry->getElementsByTagNameNS(self::POLL_OBJECT, 'poll'); + $responseElements = $activity->entry->getElementsByTagNameNS(self::POLL_OBJECT, 'response'); + if ($dataElements->length) { + $data = $dataElements->item(0); $question = $data->getAttribute('question'); $opts = array(); foreach ($data->attributes as $node) { @@ -230,6 +231,25 @@ class PollPlugin extends MicroAppPlugin } catch (Exception $e) { common_log(LOG_DEBUG, "YYY fail: " . $e->getMessage()); } + } else if ($responseElements->length) { + $data = $responseElements->item(0); + $pollUri = $data->getAttribute('poll'); + $selection = intval($data->getAttribute('selection')); + + if (!$pollUri) { + throw new Exception('Invalid poll response: no poll reference.'); + } + $poll = Poll::staticGet('uri', $pollUri); + if (!$poll) { + throw new Exception('Invalid poll response: poll is unknown.'); + } + try { + $notice = Poll_response::saveNew($profile, $poll, $selection, $options); + common_log(LOG_DEBUG, "YYY response ok: " . $notice->id); + return $notice; + } catch (Exception $e) { + common_log(LOG_DEBUG, "YYY response fail: " . $e->getMessage()); + } } else { common_log(LOG_DEBUG, "YYY no poll data"); } @@ -240,11 +260,61 @@ class PollPlugin extends MicroAppPlugin { assert($this->isMyNotice($notice)); + switch ($notice->object_type) { + case self::POLL_OBJECT: + return $this->activityObjectFromNoticePoll($notice); + case self::POLL_RESPONSE_OBJECT: + return $this->activityObjectFromNoticePollResponse($notice); + default: + throw new Exception('Unexpected type for poll plugin: ' . $notice->object_type); + } + } + + function activityObjectFromNoticePoll($notice) + { $object = new ActivityObject(); $object->id = $notice->uri; $object->type = self::POLL_OBJECT; - $object->title = 'Poll title'; - $object->summary = 'Poll summary'; + $object->title = $notice->content; + $object->summary = $notice->content; + $object->link = $notice->bestUrl(); + + $response = Poll_response::getByNotice($notice); + $poll = $response->getPoll(); + + /** + * For the moment, using a kind of icky-looking schema that happens to + * work with out code for generating both Atom and JSON forms, though + * I don't like it: + * + * + * + * "poll:response": { + * "xmlns:poll": http://apinamespace.org/activitystreams/object/poll + * "uri": "http://..../poll/...." + * "selection": 3 + * } + * + */ + // @fixme there's no way to specify an XML node tree here, like + // @fixme there's no way to specify a JSON array or multi-level tree unless you break the XML attribs + // @fixme XML node contents don't get shown in JSON + $data = array('xmlns:poll' => self::POLL_OBJECT, + 'poll' => $poll->uri, + 'selection' => intval($response->selection)); + $object->extra[] = array('poll:response', $data, ''); + return $object; + } + + function activityObjectFromNoticePollResponse($notice) + { + $object = new ActivityObject(); + $object->id = $notice->uri; + $object->type = self::POLL_RESPONSE_OBJECT; + $object->title = $notice->content; + $object->summary = $notice->content; $object->link = $notice->bestUrl(); $poll = Poll::getByNotice($notice); @@ -262,7 +332,7 @@ class PollPlugin extends MicroAppPlugin * option2="Option two" * option3="Option three"> * - * "poll:data": { + * "poll:response": { * "xmlns:poll": http://apinamespace.org/activitystreams/object/poll * "question": "Who wants a poll question?" * "option1": "Option one" @@ -279,7 +349,7 @@ class PollPlugin extends MicroAppPlugin foreach ($poll->getOptions() as $i => $opt) { $data['option' . ($i + 1)] = $opt; } - $object->extra[] = array('poll:data', $data, ''); + $object->extra[] = array('poll:poll', $data, ''); return $object; } diff --git a/plugins/Poll/Poll_response.php b/plugins/Poll/Poll_response.php index b5204c71f0..03dd6f60b5 100644 --- a/plugins/Poll/Poll_response.php +++ b/plugins/Poll/Poll_response.php @@ -158,10 +158,10 @@ class Poll_response extends Managed_DataObject $options = array(); } - $opts = $poll->getOptions(); - if ($selection < 1 || $selection > count($opts)) { + if (!$poll->isValidSelection($selection)) { throw new ClientException(_m('Invalid poll selection.')); } + $opts = $poll->getOptions(); $answer = $opts[$selection - 1]; $pr = new Poll_response();