aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormarcus <marcus@36083f99-b078-4883-b0ff-0f9b5a30f544>2008-07-15 10:54:02 +0000
committermarcus <marcus@36083f99-b078-4883-b0ff-0f9b5a30f544>2008-07-15 10:54:02 +0000
commit7bfe15a21379a4acef4b989e8bc07d4f556d9b27 (patch)
treef106525feac0b1b32bae088aeab4e6dbcc0f96c9
parentd9a7f8ee70bdd5a5a596a5bb745c8d11391105e9 (diff)
downloadelgg-7bfe15a21379a4acef4b989e8bc07d4f556d9b27.tar.gz
elgg-7bfe15a21379a4acef4b989e8bc07d4f556d9b27.tar.bz2
Closes #135: First version of the OpenDD friends elsewhere feed.
git-svn-id: https://code.elgg.org/elgg/trunk@1423 36083f99-b078-4883-b0ff-0f9b5a30f544
-rw-r--r--engine/lib/extender.php2
-rw-r--r--mod/opendd/languages/en.php3
-rw-r--r--mod/opendd/manage.php2
-rw-r--r--mod/opendd/start.php342
-rw-r--r--mod/opendd/viewfeed.php2
-rw-r--r--mod/opendd/views/default/widgets/opendd_friends_elsewhere/edit.php20
-rw-r--r--mod/opendd/views/default/widgets/opendd_friends_elsewhere/view.php28
7 files changed, 398 insertions, 1 deletions
diff --git a/engine/lib/extender.php b/engine/lib/extender.php
index 74b2d5af7..a996f33bf 100644
--- a/engine/lib/extender.php
+++ b/engine/lib/extender.php
@@ -254,7 +254,7 @@
$type = $element->getAttribute('type');
$attr_name = $element->getAttribute('name');
$attr_val = $element->getBody();
-
+
switch ($type)
{
case 'annotation' :
diff --git a/mod/opendd/languages/en.php b/mod/opendd/languages/en.php
index 08f764728..a3bd61324 100644
--- a/mod/opendd/languages/en.php
+++ b/mod/opendd/languages/en.php
@@ -45,7 +45,10 @@
'opendd:published' => "Published",
'opendd:nodata' => "There was a problem getting the feed, response: %s",
+ 'opendd:noriver' => "No data currently available.",
+ 'opendd:widgets:elsewhere:title' => "Friends elsewhere",
+ 'opendd:widgets:elsewhere:description' => "This widget uses OpenDD to display your friends on other sites.",
);
add_translation("en",$english);
diff --git a/mod/opendd/manage.php b/mod/opendd/manage.php
index 22c5ace3f..1fc63b550 100644
--- a/mod/opendd/manage.php
+++ b/mod/opendd/manage.php
@@ -9,6 +9,8 @@
* @link http://elgg.com/
*/
+ gatekeeper();
+
$limit = get_input("limit", 10);
$offset = get_input("offset", 0);
diff --git a/mod/opendd/start.php b/mod/opendd/start.php
index 88891ba11..ff2e751bd 100644
--- a/mod/opendd/start.php
+++ b/mod/opendd/start.php
@@ -40,6 +40,8 @@
// Extend some views
extend_view('css','opendd/css');
+ // Register some widgets
+ add_widget_type('opendd_friends_elsewhere',elgg_echo('opendd:widgets:elsewhere:title'), elgg_echo('opendd:widgets:elsewhere:description'));
// Subscribe fields
$CONFIG->opendd = array(
@@ -110,6 +112,346 @@
return $CONFIG->wwwroot . "pg/opendd/" . $feed->getOwnerEntity()->username . "/view/{$feed->guid}";
}
+ /**
+ * Return a list of feed urls for a given user.
+ *
+ * @param int $user_guid User in question
+ * @return array
+ */
+ function opendd_get_feed_urls($user_guid)
+ {
+ $feeds = array();
+
+ $feed_entities = get_entities('object', 'oddfeed', $user_guid);
+ if ($feed_entities)
+ {
+ foreach ($feed_entities as $feed)
+ $feeds[] = $feed->feedurl;
+ }
+
+ if (count($feeds))
+ return $feeds;
+
+ return false;
+ }
+
+ /**
+ * Fetch a given UUID.
+ *
+ * @param string $uuid The uuid
+ * @return ODDDocument
+ */
+ function opendd_fetch_uuid($uuid)
+ {
+ $ctx = stream_context_create(array(
+ 'http' => array(
+ 'timeout' => 1
+ )
+ )
+ );
+
+ $feed_data = ODD_Import(file_get_contents($uuid));//, 0, $ctx));
+ if ($feed_data)
+ return $feed_data;
+
+ return NULL;
+ }
+
+ // Array of ODD objects mapped to uuid
+ $uuid_array = array();
+
+ // Array of ElggEntities mapped to uuid
+ $elgg_array = array();
+
+ /**
+ * Combines opendd_odd_to_elgg and opendd_fetch_uuid and fetch a single uuid and return an object or an array
+ * suitable for the ElggRiverStatement Object.
+ *
+ * @param string $uuid The UUID
+ * @return mixed
+ */
+ function opendd_fetch_to_elgg($uuid)
+ {
+ global $uuid_array, $elgg_array;
+
+ if (!isset($uuid_array[$uuid]))
+ $uuid_array[$uuid] = opendd_fetch_uuid($uuid);
+ if ((!isset($elgg_array[$uuid])) && (isset($uuid_array[$uuid])))
+ $elgg_array[$uuid] = opendd_odd_to_elgg($uuid_array[$uuid]);
+
+ if ($elgg_array[$uuid])
+ return $elgg_array[$uuid];
+
+ return false;
+ }
+
+ /**
+ * Construct an Elgg object out of a given element and its metadata (like import without doing any saving).
+ * This does not function if you are sending a relationship... this is a special case and is returned as an unchanged
+ * ODDRelationship (since it is objects are not being saved and so guids are currently meaningless.)
+ *
+ * TODO: Optimise so that it caches uuids (shared with other uuid cache)
+ *
+ * @param ODDDocument $element
+ */
+ function opendd_odd_to_elgg(ODDDocument $element)
+ {
+ global $uuid_array, $elgg_array;
+
+ $count = $element->getNumElements();
+
+ if ($count==1)
+ {
+ // Atomic component - relationship or metadata;
+ $elements = $element->getElements();
+ $e = $elements[0];
+ if ($e instanceof ODDRelationship)
+ {
+ // Return statement object array
+ $object = array();
+ $object['subject'] = opendd_fetch_to_elgg($e->getAttribute('uuid1'));
+ $object['relationship'] = $e->getAttribute('type');
+ $object['object'] = opendd_fetch_to_elgg($e->getAttribute('uuid2'));
+
+ return $object;
+ }
+
+ if ($e instanceof ODDMetaData)
+ {
+ $type = $e->getAttribute('type');
+ $attr_name = $e->getAttribute('name');
+ $attr_val = $e->getBody();
+
+ $subject = NULL;
+ switch ($type)
+ {
+ case 'annotation' :
+ $subject = new ElggAnnotation();
+ break;
+ case 'metadata' :
+ default:
+ $subject = new ElggMetaData();
+ break;
+ }
+
+ $subject->name = $attr_name;
+ $subject->value = $attr_value;
+ $subject->type = $type;
+ $subject->time_created = $e->getAttribute('published');
+
+ $object = array('subject' => $subject, 'object' => opendd_fetch_to_elgg($e->getAttribute('entity_uuid')));
+
+ return $object;
+ }
+ }
+ else
+ {
+
+ $tmp = array();
+ // Go through the elements
+ $spoo;
+ foreach ($element as $e)
+ {
+ $uuid = $e->getAttribute('uuid');
+
+ // if entity then create
+ if ($e instanceof ODDEntity) {
+ $tmp[$uuid] = oddentity_to_elggentity($e);
+ $spoo = $uuid;
+ }
+
+ // if metadata then add to entity
+ if ($e instanceof ODDMetaData) {
+
+ $entity_uuid = $e->getAttribute('entity_uuid');
+ oddmetadata_to_elggextender($tmp[$entity_uuid], $e);
+ }
+
+ }
+
+ foreach ($tmp as $t)
+ return $t;
+
+ }
+ }
+
+ /**
+ * ISSUES
+ *
+ * - opendd feed doesn't work
+ * - all entities need to be public on target
+ * - setobject on statement is incorrect
+ * - NEED WAY TO GET CLASS!
+ *
+ */
+
+
+ /**
+ * This function provides a river-like view for remote friend feeds from multiple sources.
+ * It will produce an aggregation of the feeds and render them in a similar way to get_river_entries();
+ *
+ * TODO: How do we handle metadata in this instance? - It needs to refer to the object.
+ *
+ * @param array $feeds List of Opendd feed urls.
+ * @param int $limit Maximum results to process.
+ * @param int $offset The offset.
+ */
+ function opendd_aggregate_remote_river(array $feeds, $limit = 10, $offset = 0)
+ {
+ global $uuid_array, $elgg_array;
+
+ $river = array();
+ $opendd_elements = array();
+ $opendd_published = array();
+
+ // set start limit and offset
+ $cnt = $limit; // Didn' cast to int here deliberately
+ $off = $offset; // here too
+
+ $ctx = stream_context_create(array(
+ 'http' => array(
+ 'timeout' => 1
+ )
+ )
+ );
+
+ // Get feeds
+ foreach ($feeds as $feed)
+ {
+ // Retrieve feed
+ $feed_data = ODD_Import(file_get_contents($feed, 0, $ctx));
+
+ if ($feed_data)
+ {
+ $elements = $feed_data->getElements();
+ foreach ($elements as $e)
+ $opendd_elements[] = $e;
+
+ foreach ($opendd_elements as $k => $v)
+ $opendd_published[$k] = $v->getPublishedAsTime();
+ }
+ }
+
+ // Sort by date (desc)
+ arsort($opendd_published);
+ $sorted_odd_elements = array();
+
+ foreach ($opendd_published as $k => $v)
+ $sorted_odd_elements[] = $opendd_elements[$k];
+
+
+ // Array of ODD objects mapped to uuid
+ $uuid_array = array();
+
+ // Array of ElggEntities mapped to uuid
+ $elgg_array = array();
+
+ $exit = true;
+
+ do
+ {
+ if (!count($sorted_odd_elements))
+ $exit = true;
+ else
+ {
+ foreach ($sorted_odd_elements as $oddelement)
+ {
+ $statement = NULL;
+
+ // Valid ODD activity streams can only be relationships!
+ if ($oddelement instanceof ODDRelationship)
+ {
+ $uuid1 = $oddelement->getAttribute('uuid1');
+ $uuid2 = $oddelement->getAttribute('uuid2');
+
+ // Construct our new statement
+ $subject = opendd_fetch_to_elgg($uuid1);
+ $event = $oddelement->getAttribute('type');
+ $object = opendd_fetch_to_elgg($uuid2);
+ $time = $oddelement->getPublishedAsTime();
+
+ $statement = new ElggRiverStatement($subject, $event, $object);
+
+ // Work out class
+ if ($object instanceof ElggEntity)
+ $class = get_class($object);
+ else if (count($object)==3)
+ $class = 'ElggRelationship';
+ else
+ $class = get_class($object['subject']);
+
+
+ }
+
+ // If no fatal errors while extracting the necessary data then continue
+ if (($subject) && ($object) && ($event) && ($statement))
+ {
+ // We have constructed the information
+
+ if ($object instanceof ElggEntity) {
+ $subtype = $object->getSubtype();
+ } else {
+ $subtype = "";
+ }
+ if ($subtype == "widget") {
+ $subtype = "widget/" . $object->handler;
+ }
+
+ if (!empty($subtype) && elgg_view_exists("river/{$subtype}/{$event}")) {
+ $tam = elgg_view("river/{$subtype}/$event", array(
+ 'statement' => $statement
+ ));
+ } else if (elgg_view_exists("river/$class/$event")) {
+ $tam = elgg_view("river/$class/$event", array(
+ 'statement' => $statement
+ ));
+
+ }
+
+ if (!empty($tam)) {
+ $tam = elgg_view("river/wrapper",array(
+ 'entry' => $tam,
+ 'time' => $time,
+ 'event' => $event,
+ 'statement' => $statement
+ ));
+ }
+
+ if ($tam)
+ {
+ $river[] = $tam;
+ $cnt--;
+ }
+
+
+ }
+ /*else
+ {
+ echo "$uuid2\n";
+ print_r($object);
+ print_r($statement);
+
+ die();
+ }*/
+
+ if ($cnt == 0 ) break; // crufty
+
+ // Increase offset
+ $off++;
+ }
+ }
+
+ } while (
+ ($cnt > 0) &&
+ (!$exit)
+ );
+
+
+ return $river;
+
+
+ }
+
// Make sure the groups initialisation function is called on initialisation
register_elgg_event_handler('init','system','opendd_init');
diff --git a/mod/opendd/viewfeed.php b/mod/opendd/viewfeed.php
index a581c834e..7cec15884 100644
--- a/mod/opendd/viewfeed.php
+++ b/mod/opendd/viewfeed.php
@@ -11,6 +11,8 @@
require_once(dirname(dirname(dirname(__FILE__))) . "/engine/start.php");
+ gatekeeper();
+
$entity = get_entity(get_input('feed_guid'));
$limit = get_input("limit", 10);
$offset = get_input("offset", 0);
diff --git a/mod/opendd/views/default/widgets/opendd_friends_elsewhere/edit.php b/mod/opendd/views/default/widgets/opendd_friends_elsewhere/edit.php
new file mode 100644
index 000000000..2b912f567
--- /dev/null
+++ b/mod/opendd/views/default/widgets/opendd_friends_elsewhere/edit.php
@@ -0,0 +1,20 @@
+<?php
+ /**
+ * Elgg OpenDD aggregator
+ *
+ * @package ElggOpenDD
+ * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2
+ * @author Marcus Povey
+ * @copyright Curverider Ltd 2008
+ * @link http://elgg.com/
+ */
+
+ $feeds = opendd_get_feed_urls(page_owner());
+
+
+ echo elgg_view('input/checkboxes', array(
+ 'internalname' => 'params[feeds]',
+ 'options' => $feeds,
+ 'value' => $vars['entity']->feeds
+ ));
+?> \ No newline at end of file
diff --git a/mod/opendd/views/default/widgets/opendd_friends_elsewhere/view.php b/mod/opendd/views/default/widgets/opendd_friends_elsewhere/view.php
new file mode 100644
index 000000000..9edeabc09
--- /dev/null
+++ b/mod/opendd/views/default/widgets/opendd_friends_elsewhere/view.php
@@ -0,0 +1,28 @@
+<?php
+ /**
+ * Elgg OpenDD aggregator
+ *
+ * @package ElggOpenDD
+ * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2
+ * @author Marcus Povey
+ * @copyright Curverider Ltd 2008
+ * @link http://elgg.com/
+ */
+include ("../../../../../../engine/start.php");
+
+$vars['entity'] = get_entity(80);
+
+ $owner = page_owner_entity();
+ $limit = 8;
+
+ if ($vars['entity']->limit)
+ $limit = $vars['entity']->limit;
+
+ $river = opendd_aggregate_remote_river($vars['entity']->feeds, $limit, $offset);
+
+
+ if ($river)
+ echo elgg_view('river/dashboard', array('river' => $river));
+ else
+ echo elgg_echo("opendd:noriver");
+?> \ No newline at end of file