diff --git a/classes/Notice.php b/classes/Notice.php index 3891f431e4..beb6c4fe6a 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -1544,9 +1544,9 @@ class Notice extends Managed_DataObject $attachments = $this->attachments(); foreach ($attachments as $attachment) { - $enclosure = $attachment->getEnclosure(); - if ($enclosure) { - $act->enclosures[] = $enclosure; + // Save local attachments + if (!empty($attachment->filename)) { + $act->attachments[] = ActivityObject::fromFile($attachment); } } diff --git a/lib/activity.php b/lib/activity.php index 2ec2176d39..ecae96b50a 100644 --- a/lib/activity.php +++ b/lib/activity.php @@ -100,6 +100,7 @@ class Activity public $title; // title of the activity public $categories = array(); // list of AtomCategory objects public $enclosures = array(); // list of enclosure URL references + public $attachments = array(); // list of attachments public $extra = array(); // extra elements as array(tag, attrs, content) public $source; // ActivitySource object representing 'home feed' @@ -397,47 +398,11 @@ class Activity $activity['object']['objectType'] = 'activity'; } - - // Instead of adding enclosures as an extension to JSON - // Activities, it seems like we should be using the - // attachements property of ActivityObject - - $attachments = array(); - - // XXX: OK, this is kinda cheating. We should probably figure out - // what kind of objects these are based on mime-type and then - // create specific object types. Right now this rely on - // duck-typing. Also, we should include an embed code for - // video attachments. - - foreach ($this->enclosures as $enclosure) { - - if (is_string($enclosure)) { - - $attachments[]['id'] = $enclosure; - - } else { - - $attachments[]['id'] = $enclosure->url; - - $mediaLink = new ActivityStreamsMediaLink( - $enclosure->url, - null, - null, - $enclosure->mimetype - // XXX: Add 'size' as an extension to MediaLink? - ); - - $attachments[]['mediaLink'] = $mediaLink->asArray(); // extension - - if ($enclosure->title) { - $attachments[]['displayName'] = $enclosure->title; - } + foreach ($this->attachments as $attachment) { + if (empty($activity['object']['attachments'])) { + $activity['object']['attachments'] = array(); } - } - - if (!empty($attachments)) { - $activity['object']['attachments'] = $attachments; + $activity['object']['attachments'][] = $attachment->asArray(); } } diff --git a/lib/activityobject.php b/lib/activityobject.php index 0eff87146f..1a81d30687 100644 --- a/lib/activityobject.php +++ b/lib/activityobject.php @@ -70,6 +70,7 @@ class ActivityObject // ^^^^^^^^^^ tea! const ACTIVITY = 'http://activitystrea.ms/schema/1.0/activity'; const SERVICE = 'http://activitystrea.ms/schema/1.0/service'; + const IMAGE = 'http://activitystrea.ms/schema/1.0/image'; // Atom elements we snarf @@ -111,6 +112,8 @@ class ActivityObject public $description; public $extra = array(); + public $stream; + /** * Constructor * @@ -549,6 +552,46 @@ class ActivityObject return $object; } + static function fromFile(File $file) + { + $object = new ActivityObject(); + + if (Event::handle('StartActivityObjectFromFile', array($file, &$object))) { + + $object->type = self::mimeTypeToObjectType($file->mimetype); + $object->id = TagURI::mint(sprintf("file:%d", $file->id)); + $object->link = common_local_url('attachment', array('id' => $file->id)); + + if ($file->title) { + $object->title = $file->title; + } + + if ($file->date) { + $object->date = $file->date; + } + + $thumbnail = $file->getThumbnail(); + + if (!empty($thumbnail)) { + $object->thumbnail = $thumbnail; + } + + switch ($object->type) { + case ActivityObject::IMAGE: + $object->largerImage = $file->url; + break; + case ActivityObject::VIDEO: + case ActivityObject::AUDIO: + $object->stream = $file->url; + break; + } + + Event::handle('EndActivityObjectFromFile', array($file, &$object)); + } + + return $object; + } + function outputTo($xo, $tag='activity:object') { if (!empty($tag)) { @@ -809,6 +852,34 @@ class ActivityObject $object['portablecontacts_net'] = array_filter($this->poco->asArray()); } + if (!empty($this->thumbnail)) { + if (is_string($this->thumbnail)) { + $object['image'] = array('url' => $this->thumbnail); + } else { + $object['image'] = array('url' => $this->thumbnail->url); + if ($this->thumbnail->width) { + $object['image']['width'] = $this->thumbnail->width; + } + if ($this->thumbnail->height) { + $object['image']['height'] = $this->thumbnail->height; + } + } + } + + switch ($object->type) { + case self::IMAGE: + if (!empty($this->largerImage)) { + $object['fullImage'] = array('url' => $this->largerImage); + } + break; + case self::AUDIO: + case self::VIDEO: + if (!empty($this->stream)) { + $object['stream'] = array('url' => $this->stream); + } + break; + } + Event::handle('EndActivityObjectOutputJson', array($this, &$object)); } return array_filter($object); @@ -822,4 +893,25 @@ class ActivityObject return $type; } } + + static function mimeTypeToObjectType($mimeType) { + $ot = null; + $parts = explode('/', $mimeType); + + switch ($parts[0]) { + case 'image': + $ot = self::IMAGE; + break; + case 'audio': + $ot = self::AUDIO; + break; + case 'video': + $ot = self::VIDEO; + break; + default: + $ot = self::FILE; + } + + return $ot; + } }