Merge branch 'atomic-json' into 1.0.x
This commit is contained in:
commit
3c9561b3f0
16
EVENTS.txt
16
EVENTS.txt
@ -1115,3 +1115,19 @@ StartGroupProfileElements: Start showing stuff about the group on its profile pa
|
|||||||
EndGroupProfileElements: Start showing stuff about the group on its profile page
|
EndGroupProfileElements: Start showing stuff about the group on its profile page
|
||||||
- $action: action being executed (for output and params)
|
- $action: action being executed (for output and params)
|
||||||
- $group: group for the page
|
- $group: group for the page
|
||||||
|
|
||||||
|
StartActivityObjectOutputAtom: Called at start of Atom XML output generation for ActivityObject chunks, just inside the <activity:object>. Cancel the event to take over its output completely (you're responsible for calling the matching End event if so)
|
||||||
|
- $obj: ActivityObject
|
||||||
|
- $out: XMLOutputter to append custom output
|
||||||
|
|
||||||
|
EndActivityObjectOutputAtom: Called at end of Atom XML output generation for ActivityObject chunks, just inside the </activity:object>
|
||||||
|
- $obj: ActivityObject
|
||||||
|
- $out: XMLOutputter to append custom output
|
||||||
|
|
||||||
|
StartActivityObjectOutputJson: Called at start of JSON output generation for ActivityObject chunks: the array has not yet been filled out. Cancel the event to take over its output completely (you're responsible for calling the matching End event if so)
|
||||||
|
- $obj ActivityObject
|
||||||
|
- &$out: array to be serialized; you're free to modify it
|
||||||
|
|
||||||
|
EndActivityObjectOutputJson: Called at end of JSON output generation for ActivityObject chunks: the array has not yet been filled out.
|
||||||
|
- $obj ActivityObject
|
||||||
|
- &$out: array to be serialized; you're free to modify it
|
||||||
|
@ -533,6 +533,7 @@ class ActivityObject
|
|||||||
$xo->elementStart($tag);
|
$xo->elementStart($tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Event::handle('StartActivityObjectOutputAtom', array($this, $xo))) {
|
||||||
$xo->element('activity:object-type', null, $this->type);
|
$xo->element('activity:object-type', null, $this->type);
|
||||||
|
|
||||||
// <author> uses URI
|
// <author> uses URI
|
||||||
@ -620,6 +621,9 @@ class ActivityObject
|
|||||||
$xo->element($extraTag, $attrs, $content);
|
$xo->element($extraTag, $attrs, $content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Event::handle('EndActivityObjectOutputAtom', array($this, $xo));
|
||||||
|
}
|
||||||
|
|
||||||
if (!empty($tag)) {
|
if (!empty($tag)) {
|
||||||
$xo->elementEnd($tag);
|
$xo->elementEnd($tag);
|
||||||
}
|
}
|
||||||
@ -647,6 +651,7 @@ class ActivityObject
|
|||||||
{
|
{
|
||||||
$object = array();
|
$object = array();
|
||||||
|
|
||||||
|
if (Event::handle('StartActivityObjectOutputJson', array($this, &$object))) {
|
||||||
// XXX: attachedObjects are added by Activity
|
// XXX: attachedObjects are added by Activity
|
||||||
|
|
||||||
// displayName
|
// displayName
|
||||||
@ -734,7 +739,8 @@ class ActivityObject
|
|||||||
if (!empty($this->poco)) {
|
if (!empty($this->poco)) {
|
||||||
$object['contact'] = $this->poco->asArray();
|
$object['contact'] = $this->poco->asArray();
|
||||||
}
|
}
|
||||||
|
Event::handle('EndActivityObjectOutputJson', array($this, &$object));
|
||||||
|
}
|
||||||
return array_filter($object);
|
return array_filter($object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,6 +212,44 @@ abstract class MicroAppPlugin extends Plugin
|
|||||||
in_array($activity->objects[0]->type, $types));
|
in_array($activity->objects[0]->type, $types));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when generating Atom XML ActivityStreams output from an
|
||||||
|
* ActivityObject belonging to this plugin. Gives the plugin
|
||||||
|
* a chance to add custom output.
|
||||||
|
*
|
||||||
|
* Note that you can only add output of additional XML elements,
|
||||||
|
* not change existing stuff here.
|
||||||
|
*
|
||||||
|
* If output is already handled by the base Activity classes,
|
||||||
|
* you can leave this base implementation as a no-op.
|
||||||
|
*
|
||||||
|
* @param ActivityObject $obj
|
||||||
|
* @param XMLOutputter $out to add elements at end of object
|
||||||
|
*/
|
||||||
|
function activityObjectOutputAtom(ActivityObject $obj, XMLOutputter $out)
|
||||||
|
{
|
||||||
|
// default is a no-op
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when generating JSON ActivityStreams output from an
|
||||||
|
* ActivityObject belonging to this plugin. Gives the plugin
|
||||||
|
* a chance to add custom output.
|
||||||
|
*
|
||||||
|
* Modify the array contents to your heart's content, and it'll
|
||||||
|
* all get serialized out as JSON.
|
||||||
|
*
|
||||||
|
* If output is already handled by the base Activity classes,
|
||||||
|
* you can leave this base implementation as a no-op.
|
||||||
|
*
|
||||||
|
* @param ActivityObject $obj
|
||||||
|
* @param array &$out JSON-targeted array which can be modified
|
||||||
|
*/
|
||||||
|
public function activityObjectOutputJson(ActivityObject $obj, array &$out)
|
||||||
|
{
|
||||||
|
// default is a no-op
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When a notice is deleted, delete the related objects
|
* When a notice is deleted, delete the related objects
|
||||||
* by calling the overridable $this->deleteRelated().
|
* by calling the overridable $this->deleteRelated().
|
||||||
@ -439,6 +477,46 @@ abstract class MicroAppPlugin extends Plugin
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event handler gives the plugin a chance to add custom
|
||||||
|
* Atom XML ActivityStreams output from a previously filled-out
|
||||||
|
* ActivityObject.
|
||||||
|
*
|
||||||
|
* The atomOutput method is called if it's one of
|
||||||
|
* our matching types.
|
||||||
|
*
|
||||||
|
* @param ActivityObject $obj
|
||||||
|
* @param XMLOutputter $out to add elements at end of object
|
||||||
|
* @return boolean hook return value
|
||||||
|
*/
|
||||||
|
function onEndActivityObjectOutputAtom(ActivityObject $obj, XMLOutputter $out)
|
||||||
|
{
|
||||||
|
if (in_array($obj->type, $this->types())) {
|
||||||
|
$this->activityObjectOutputAtom($obj, $out);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event handler gives the plugin a chance to add custom
|
||||||
|
* JSON ActivityStreams output from a previously filled-out
|
||||||
|
* ActivityObject.
|
||||||
|
*
|
||||||
|
* The activityObjectOutputJson method is called if it's one of
|
||||||
|
* our matching types.
|
||||||
|
*
|
||||||
|
* @param ActivityObject $obj
|
||||||
|
* @param array &$out JSON-targeted array which can be modified
|
||||||
|
* @return boolean hook return value
|
||||||
|
*/
|
||||||
|
function onEndActivityObjectOutputJson(ActivityObject $obj, array &$out)
|
||||||
|
{
|
||||||
|
if (in_array($obj->type, $this->types())) {
|
||||||
|
$this->activityObjectOutputJson($obj, &$out);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function onStartShowEntryForms(&$tabs)
|
function onStartShowEntryForms(&$tabs)
|
||||||
{
|
{
|
||||||
$tabs[$this->tag()] = $this->appTitle();
|
$tabs[$this->tag()] = $this->appTitle();
|
||||||
|
@ -48,8 +48,8 @@ class PollPlugin extends MicroAppPlugin
|
|||||||
const VERSION = '0.1';
|
const VERSION = '0.1';
|
||||||
|
|
||||||
// @fixme which domain should we use for these namespaces?
|
// @fixme which domain should we use for these namespaces?
|
||||||
const POLL_OBJECT = 'http://apinamespace.org/activitystreams/object/poll';
|
const POLL_OBJECT = 'http://activityschema.org/object/poll';
|
||||||
const POLL_RESPONSE_OBJECT = 'http://apinamespace.org/activitystreams/object/poll-response';
|
const POLL_RESPONSE_OBJECT = 'http://activityschema.org/object/poll-response';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Database schema setup
|
* Database schema setup
|
||||||
@ -203,26 +203,22 @@ class PollPlugin extends MicroAppPlugin
|
|||||||
$pollElements = $activity->entry->getElementsByTagNameNS(self::POLL_OBJECT, 'poll');
|
$pollElements = $activity->entry->getElementsByTagNameNS(self::POLL_OBJECT, 'poll');
|
||||||
$responseElements = $activity->entry->getElementsByTagNameNS(self::POLL_OBJECT, 'response');
|
$responseElements = $activity->entry->getElementsByTagNameNS(self::POLL_OBJECT, 'response');
|
||||||
if ($pollElements->length) {
|
if ($pollElements->length) {
|
||||||
$data = $pollElements->item(0);
|
$question = '';
|
||||||
$question = $data->getAttribute('question');
|
|
||||||
$opts = array();
|
$opts = array();
|
||||||
foreach ($data->attributes as $node) {
|
|
||||||
$name = $node->nodeName;
|
$data = $pollElements->item(0);
|
||||||
if (substr($name, 0, 6) == 'option') {
|
foreach ($data->getElementsByTagNameNS(self::POLL_OBJECT, 'question') as $node) {
|
||||||
$n = intval(substr($name, 6));
|
$question = $node->textContent;
|
||||||
if ($n > 0) {
|
|
||||||
$opts[$n - 1] = $node->nodeValue;
|
|
||||||
}
|
}
|
||||||
|
foreach ($data->getElementsByTagNameNS(self::POLL_OBJECT, 'option') as $node) {
|
||||||
|
$opts[] = $node->textContent;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
common_log(LOG_DEBUG, "YYY question: $question");
|
|
||||||
common_log(LOG_DEBUG, "YYY opts: " . var_export($opts, true));
|
|
||||||
try {
|
try {
|
||||||
$notice = Poll::saveNew($profile, $question, $opts, $options);
|
$notice = Poll::saveNew($profile, $question, $opts, $options);
|
||||||
common_log(LOG_DEBUG, "YYY ok: " . $notice->id);
|
common_log(LOG_DEBUG, "Saved Poll from ActivityStream data ok: notice id " . $notice->id);
|
||||||
return $notice;
|
return $notice;
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
common_log(LOG_DEBUG, "YYY fail: " . $e->getMessage());
|
common_log(LOG_DEBUG, "Poll save from ActivityStream data failed: " . $e->getMessage());
|
||||||
}
|
}
|
||||||
} else if ($responseElements->length) {
|
} else if ($responseElements->length) {
|
||||||
$data = $responseElements->item(0);
|
$data = $responseElements->item(0);
|
||||||
@ -240,10 +236,10 @@ class PollPlugin extends MicroAppPlugin
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
$notice = Poll_response::saveNew($profile, $poll, $selection, $options);
|
$notice = Poll_response::saveNew($profile, $poll, $selection, $options);
|
||||||
common_log(LOG_DEBUG, "YYY response ok: " . $notice->id);
|
common_log(LOG_DEBUG, "Saved Poll_response ok, notice id: " . $notice->id);
|
||||||
return $notice;
|
return $notice;
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
common_log(LOG_DEBUG, "YYY response fail: " . $e->getMessage());
|
common_log(LOG_DEBUG, "Poll response save fail: " . $e->getMessage());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
common_log(LOG_DEBUG, "YYY no poll data");
|
common_log(LOG_DEBUG, "YYY no poll data");
|
||||||
@ -277,33 +273,15 @@ class PollPlugin extends MicroAppPlugin
|
|||||||
$object->link = $notice->bestUrl();
|
$object->link = $notice->bestUrl();
|
||||||
|
|
||||||
$response = Poll_response::getByNotice($notice);
|
$response = Poll_response::getByNotice($notice);
|
||||||
if (!$response) {
|
if ($response) {
|
||||||
common_log(LOG_DEBUG, "QQQ notice uri: $notice->uri");
|
|
||||||
} else {
|
|
||||||
$poll = $response->getPoll();
|
$poll = $response->getPoll();
|
||||||
/**
|
if ($poll) {
|
||||||
* For the moment, using a kind of icky-looking schema that happens to
|
// Stash data to be formatted later by
|
||||||
* work with out code for generating both Atom and JSON forms, though
|
// $this->activityObjectOutputAtom() or
|
||||||
* I don't like it:
|
// $this->activityObjectOutputJson()...
|
||||||
*
|
$object->pollSelection = intval($response->selection);
|
||||||
* <poll:response xmlns:poll="http://apinamespace.org/activitystreams/object/poll"
|
$object->pollUri = $poll->uri;
|
||||||
* poll="http://..../poll/...."
|
}
|
||||||
* selection="3" />
|
|
||||||
*
|
|
||||||
* "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 <poll><option/><option/></poll>
|
|
||||||
// @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;
|
return $object;
|
||||||
}
|
}
|
||||||
@ -318,41 +296,112 @@ class PollPlugin extends MicroAppPlugin
|
|||||||
$object->link = $notice->bestUrl();
|
$object->link = $notice->bestUrl();
|
||||||
|
|
||||||
$poll = Poll::getByNotice($notice);
|
$poll = Poll::getByNotice($notice);
|
||||||
/**
|
if ($poll) {
|
||||||
* Adding the poll-specific data. There's no standard in AS for polls,
|
// Stash data to be formatted later by
|
||||||
* so we're making stuff up.
|
// $this->activityObjectOutputAtom() or
|
||||||
*
|
// $this->activityObjectOutputJson()...
|
||||||
* For the moment, using a kind of icky-looking schema that happens to
|
$object->pollQuestion = $poll->question;
|
||||||
* work with out code for generating both Atom and JSON forms, though
|
$object->pollOptions = $poll->getOptions();
|
||||||
* I don't like it:
|
|
||||||
*
|
|
||||||
* <poll:data xmlns:poll="http://apinamespace.org/activitystreams/object/poll"
|
|
||||||
* question="Who wants a poll question?"
|
|
||||||
* option1="Option one"
|
|
||||||
* 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"
|
|
||||||
* "option2": "Option two"
|
|
||||||
* "option3": "Option three"
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
// @fixme there's no way to specify an XML node tree here, like <poll><option/><option/></poll>
|
|
||||||
// @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,
|
|
||||||
'question' => $poll->question);
|
|
||||||
foreach ($poll->getOptions() as $i => $opt) {
|
|
||||||
$data['option' . ($i + 1)] = $opt;
|
|
||||||
}
|
}
|
||||||
$object->extra[] = array('poll:poll', $data, '');
|
|
||||||
return $object;
|
return $object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when generating Atom XML ActivityStreams output from an
|
||||||
|
* ActivityObject belonging to this plugin. Gives the plugin
|
||||||
|
* a chance to add custom output.
|
||||||
|
*
|
||||||
|
* Note that you can only add output of additional XML elements,
|
||||||
|
* not change existing stuff here.
|
||||||
|
*
|
||||||
|
* If output is already handled by the base Activity classes,
|
||||||
|
* you can leave this base implementation as a no-op.
|
||||||
|
*
|
||||||
|
* @param ActivityObject $obj
|
||||||
|
* @param XMLOutputter $out to add elements at end of object
|
||||||
|
*/
|
||||||
|
function activityObjectOutputAtom(ActivityObject $obj, XMLOutputter $out)
|
||||||
|
{
|
||||||
|
if (isset($obj->pollQuestion)) {
|
||||||
|
/**
|
||||||
|
* <poll:poll xmlns:poll="http://apinamespace.org/activitystreams/object/poll">
|
||||||
|
* <poll:question>Who wants a poll question?</poll:question>
|
||||||
|
* <poll:option>Option one</poll:option>
|
||||||
|
* <poll:option>Option two</poll:option>
|
||||||
|
* <poll:option>Option three</poll:option>
|
||||||
|
* </poll:poll>
|
||||||
|
*/
|
||||||
|
$data = array('xmlns:poll' => self::POLL_OBJECT);
|
||||||
|
$out->elementStart('poll:poll', $data);
|
||||||
|
$out->element('poll:question', array(), $obj->pollQuestion);
|
||||||
|
foreach ($obj->pollOptions as $opt) {
|
||||||
|
$out->element('poll:option', array(), $opt);
|
||||||
|
}
|
||||||
|
$out->elementEnd('poll:poll');
|
||||||
|
}
|
||||||
|
if (isset($obj->pollSelection)) {
|
||||||
|
/**
|
||||||
|
* <poll:response xmlns:poll="http://apinamespace.org/activitystreams/object/poll">
|
||||||
|
* poll="http://..../poll/...."
|
||||||
|
* selection="3" />
|
||||||
|
*/
|
||||||
|
$data = array('xmlns:poll' => self::POLL_OBJECT,
|
||||||
|
'poll' => $obj->pollUri,
|
||||||
|
'selection' => $obj->pollSelection);
|
||||||
|
$out->element('poll:response', $data, '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when generating JSON ActivityStreams output from an
|
||||||
|
* ActivityObject belonging to this plugin. Gives the plugin
|
||||||
|
* a chance to add custom output.
|
||||||
|
*
|
||||||
|
* Modify the array contents to your heart's content, and it'll
|
||||||
|
* all get serialized out as JSON.
|
||||||
|
*
|
||||||
|
* If output is already handled by the base Activity classes,
|
||||||
|
* you can leave this base implementation as a no-op.
|
||||||
|
*
|
||||||
|
* @param ActivityObject $obj
|
||||||
|
* @param array &$out JSON-targeted array which can be modified
|
||||||
|
*/
|
||||||
|
public function activityObjectOutputJson(ActivityObject $obj, array &$out)
|
||||||
|
{
|
||||||
|
common_log(LOG_DEBUG, 'QQQ: ' . var_export($obj, true));
|
||||||
|
if (isset($obj->pollQuestion)) {
|
||||||
|
/**
|
||||||
|
* "poll": {
|
||||||
|
* "question": "Who wants a poll question?",
|
||||||
|
* "options": [
|
||||||
|
* "Option 1",
|
||||||
|
* "Option 2",
|
||||||
|
* "Option 3"
|
||||||
|
* ]
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
$data = array('question' => $obj->pollQuestion,
|
||||||
|
'options' => array());
|
||||||
|
foreach ($obj->pollOptions as $opt) {
|
||||||
|
$data['options'][] = $opt;
|
||||||
|
}
|
||||||
|
$out['poll'] = $data;
|
||||||
|
}
|
||||||
|
if (isset($obj->pollSelection)) {
|
||||||
|
/**
|
||||||
|
* "pollResponse": {
|
||||||
|
* "poll": "http://..../poll/....",
|
||||||
|
* "selection": 3
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
$data = array('poll' => $obj->pollUri,
|
||||||
|
'selection' => $obj->pollSelection);
|
||||||
|
$out['pollResponse'] = $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @fixme WARNING WARNING WARNING parent class closes the final div that we
|
* @fixme WARNING WARNING WARNING parent class closes the final div that we
|
||||||
* open here, but we probably shouldn't open it here. Check parent class
|
* open here, but we probably shouldn't open it here. Check parent class
|
||||||
|
Loading…
Reference in New Issue
Block a user