3 * StatusNet, the distributed open-source microblogging tool
5 * Class for serializing Activity Streams in JSON
9 * LICENCE: This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU Affero General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Affero General Public License for more details.
19 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 * @author Zach Copley <zach@status.net>
25 * @copyright 2011 StatusNet, Inc.
26 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
27 * @link http://status.net/
30 if (!defined('STATUSNET'))
36 * A class for generating JSON documents that represent an Activity Streams
40 * @author Zach Copley <zach@status.net>
41 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
42 * @link http://status.net/
44 class ActivityStreamJSONDocument extends JSONActivityCollection
46 // Note: Lot of AS folks think the content type should be:
47 // 'application/stream+json; charset=utf-8', but this is more
48 // useful at the moment, because some programs actually understand
50 const CONTENT_TYPE = 'application/json; charset=utf-8';
52 /* Top level array representing the document */
53 protected $doc = array();
55 /* The current authenticated user */
58 /* Title of the document */
61 /* Links associated with this document */
64 /* Count of items in this document */
65 // XXX This is cryptically referred to in the spec: "The Stream serialization MAY contain a count property."
71 * @param User $cur the current authenticated user
74 function __construct($cur = null, $title = null, $items = null, $links = null, $url = null)
76 parent::__construct($items, $url);
80 /* Title of the JSON document */
81 $this->title = $title;
84 $this->count = count($this->items);
87 /* Array of links associated with the document */
88 $this->links = empty($links) ? array() : $items;
90 /* URL of a document, this document? containing a list of all the items in the stream */
91 if (!empty($this->url)) {
92 $this->url = $this->url;
97 * Set the title of the document
99 * @param String $title the title
102 function setTitle($title)
104 $this->title = $title;
107 function setUrl($url)
114 * Add more than one Item to the document
116 * @param mixed $notices an array of Notice objects or handle
120 function addItemsFromNotices($notices)
122 if (is_array($notices)) {
123 foreach ($notices as $notice) {
124 $this->addItemFromNotice($notice);
127 while ($notices->fetch()) {
128 $this->addItemFromNotice($notices);
134 * Add a single Notice to the document
136 * @param Notice $notice a Notice to add
139 function addItemFromNotice($notice)
141 $cur = empty($this->cur) ? common_current_user() : $this->cur;
143 $act = $notice->asActivity($cur);
144 $act->extra[] = $notice->noticeInfo($cur);
145 array_push($this->items, $act->asArray());
150 * Add a link to the JSON document
152 * @param string $url the URL for the link
153 * @param string $rel the link relationship
155 function addLink($url = null, $rel = null, $mediaType = null)
157 $link = new ActivityStreamsLink($url, $rel, $mediaType);
158 array_push($this->links, $link->asArray());
162 * Return the entire document as a big string of JSON
164 * @return string encoded JSON output
168 $this->doc['generator'] = 'GNU social ' . GNUSOCIAL_VERSION; // extension
169 $this->doc['title'] = $this->title;
170 $this->doc['url'] = $this->url;
171 $this->doc['totalItems'] = $this->count;
172 $this->doc['items'] = $this->items;
173 $this->doc['links'] = $this->links; // extension
174 return json_encode(array_filter($this->doc)); // filter out empty elements
180 * A class for representing MediaLinks in JSON Activities
184 * @author Zach Copley <zach@status.net>
185 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
186 * @link http://status.net/
189 class ActivityStreamsMediaLink extends ActivityStreamsLink
193 function __construct(
197 $mediaType = null, // extension
198 $rel = null, // extension
202 parent::__construct($url, $rel, $mediaType);
203 $this->linkDict = array(
204 'width' => intval($width),
205 'height' => intval($height),
206 'duration' => intval($duration)
214 array_filter($this->linkDict)
220 * Collection primarily as the root of an Activity Streams doc but can be used as the value
221 * of extension properties in a variety of situations.
223 * A valid Collection object serialization MUST contain at least the url or items properties.
225 class JSONActivityCollection {
227 /* Non-negative integer specifying the total number of activities within the stream */
228 protected $totalItems;
230 /* An array containing a listing of Objects of any object type */
233 /* IRI referencing a JSON document containing the full listing of objects in the collection */
239 * @param array $items array of activity items
240 * @param string $url url of a doc list all the objs in the collection
241 * @param int $totalItems total number of items in the collection
243 function __construct($items = null, $url = null)
245 $this->items = empty($items) ? array() : $items;
246 $this->totalItems = count($items);
251 * Get the total number of items in the collection
253 * @return int total the total
255 public function getTotalItems()
257 $this->totalItems = count($items);
258 return $this->totalItems;
263 * A class for representing links in JSON Activities
267 * @author Zach Copley <zach@status.net>
268 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
269 * @link http://status.net/
272 class ActivityStreamsLink
276 function __construct($url = null, $rel = null, $mediaType = null)
278 // links MUST have a URL
280 throw new Exception('Links must have a URL.');
283 $this->linkDict = array(
285 'rel' => $rel, // extension
286 'type' => $mediaType // extension
292 return array_filter($this->linkDict);