From 7bfe15a21379a4acef4b989e8bc07d4f556d9b27 Mon Sep 17 00:00:00 2001 From: marcus Date: Tue, 15 Jul 2008 10:54:02 +0000 Subject: 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 --- mod/opendd/languages/en.php | 3 + mod/opendd/manage.php | 2 + mod/opendd/start.php | 342 +++++++++++++++++++++ mod/opendd/viewfeed.php | 2 + .../widgets/opendd_friends_elsewhere/edit.php | 20 ++ .../widgets/opendd_friends_elsewhere/view.php | 28 ++ 6 files changed, 397 insertions(+) create mode 100644 mod/opendd/views/default/widgets/opendd_friends_elsewhere/edit.php create mode 100644 mod/opendd/views/default/widgets/opendd_friends_elsewhere/view.php (limited to 'mod/opendd') 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 @@ + '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 @@ +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 -- cgit v1.2.3