. * * @category Feed * @package StatusNet * @author Evan Prodromou * @author Zach Copley * @copyright 2010 StatusNet, Inc. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3 * @link http://status.net/ */ if (!defined('STATUSNET')) { exit(1); } class ActivityContext { public $replyToID; public $replyToUrl; public $location; public $attention = array(); public $conversation; public $forwardID; // deprecated, use ActivityVerb::SHARE instead public $forwardUrl; // deprecated, use ActivityVerb::SHARE instead const THR = 'http://purl.org/syndication/thread/1.0'; const GEORSS = 'http://www.georss.org/georss'; const OSTATUS = 'http://ostatus.org/schema/1.0'; const INREPLYTO = 'in-reply-to'; const REF = 'ref'; const HREF = 'href'; const POINT = 'point'; const ATTENTION = 'ostatus:attention'; const MENTIONED = 'mentioned'; const CONVERSATION = 'ostatus:conversation'; function __construct($element = null) { if (empty($element)) { return; } $replyToEl = ActivityUtils::child($element, self::INREPLYTO, self::THR); if (!empty($replyToEl)) { $this->replyToID = $replyToEl->getAttribute(self::REF); $this->replyToUrl = $replyToEl->getAttribute(self::HREF); } $this->location = $this->getLocation($element); $this->conversation = ActivityUtils::getLink($element, self::CONVERSATION); // Multiple attention links allowed $links = $element->getElementsByTagNameNS(ActivityUtils::ATOM, ActivityUtils::LINK); $attention = array(); for ($i = 0; $i < $links->length; $i++) { $link = $links->item($i); $linkRel = $link->getAttribute(ActivityUtils::REL); // XXX: Deprecate this in favour of "mentioned" from Salmon spec // http://salmon-protocol.googlecode.com/svn/trunk/draft-panzer-salmon-00.html#SALR if ($linkRel == self::ATTENTION) { $attention[] = $link->getAttribute(self::HREF); } elseif ($linkRel == self::MENTIONED) { $attention[] = $link->getAttribute(self::HREF); } } $this->attention = array_unique($attention); } /** * Parse location given as a GeoRSS-simple point, if provided. * http://www.georss.org/simple * * @param feed item $entry * @return mixed Location or false */ function getLocation($dom) { $points = $dom->getElementsByTagNameNS(self::GEORSS, self::POINT); for ($i = 0; $i < $points->length; $i++) { $point = $points->item($i)->textContent; return self::locationFromPoint($point); } return null; } // XXX: Move to ActivityUtils or Location? static function locationFromPoint($point) { $point = str_replace(',', ' ', $point); // per spec "treat commas as whitespace" $point = preg_replace('/\s+/', ' ', $point); $point = trim($point); $coords = explode(' ', $point); if (count($coords) == 2) { list($lat, $lon) = $coords; if (is_numeric($lat) && is_numeric($lon)) { common_log(LOG_INFO, "Looking up location for $lat $lon from georss point"); return Location::fromLatLon($lat, $lon); } } common_log(LOG_ERR, "Ignoring bogus georss:point value $point"); return null; } /** * Returns context (StatusNet stuff) as an array suitable for serializing * in JSON. Right now context stuff is an extension to Activity. * * @return array the context */ function asArray() { $context = array(); $context['replyToId'] = $this->replyToID; $context['replyToUrl'] = $this->replyToUrl; $context['conversation'] = $this->conversation; $context['forwardId'] = $this->forwardID; $context['forwardUrl'] = $this->forwardUrl; // XXX: We might want to have the attention to stuff // in here like we do with Atom return array_filter($context); } /** * Returns an array of arrays representing Activity Objects (intended to be * serialized in JSON) that represent WHO the Activity is supposed to * be received by. This is not really specified but appears in an example * of the current spec as an extension. We might want to figure out a JSON * serialization for OStatus and use that to express mentions instead. * * XXX: People's ideas on how to do this are all over the place * * @return array the array of recipients */ function getToArray() { $tos = array(); foreach ($this->attention as $attnUrl) { $to = array('id' => $attnUrl, 'url' => $attnUrl); $tos[] = $to; } return $tos; } }