1<?php 2 3/** 4 * PHP5 interface for Facebook's REST API 5 * 6 * PHP version 5.1.0+ 7 * 8 * LICENSE: This source file is subject to the New BSD license that is 9 * available through the world-wide-web at the following URI: 10 * http://www.opensource.org/licenses/bsd-license.php. If you did not receive 11 * a copy of the New BSD License and are unable to obtain it through the web, 12 * please send a note to license@php.net so we can mail you a copy immediately. 13 * 14 * @category Services 15 * @package Services_Facebook 16 * @author Joe Stump <joe@joestump.net> 17 * @copyright 2007-2008 Joe Stump <joe@joestump.net> 18 * @license http://www.opensource.org/licenses/bsd-license.php New BSD License 19 * @version Release: 0.2.14 20 * @link http://pear.php.net/package/Services_Facebook 21 */ 22 23require_once 'Services/Facebook/Common.php'; 24 25/** 26 * Facebook Feed Interface 27 * 28 * @category Services 29 * @package Services_Facebook 30 * @author Joe Stump <joe@joestump.net> 31 * @license http://www.opensource.org/licenses/bsd-license.php New BSD License 32 * @version Release: 0.2.14 33 * @link http://wiki.developers.facebook.com 34 */ 35class Services_Facebook_Feed extends Services_Facebook_Common 36{ 37 /** 38 * Publish a story to a user's feed 39 * 40 * The $images array should be a numerically indexed array of arrays, where 41 * each image has two keys: src and href. The src is the full URI of the 42 * image and the href is the link of that image. 43 * 44 * <code> 45 * <?php 46 * $images = array( 47 * array('src' => 'http://example.com/images1.jpg', 48 * 'href' => 'http://example.com/images.php?image=1'), 49 * array('src' => 'http://example.com/images2.jpg', 50 * 'href' => 'http://example.com/images.php?image=2'), 51 * array('src' => 'http://example.com/images3.jpg', 52 * 'href' => 'http://example.com/images.php?image=3') 53 * ); 54 * ?> 55 * </code> 56 * 57 * @param string $title FBML to post as story title 58 * @param string $body FBML to post as story body 59 * @param array $images Images to post to story entry 60 * 61 * @return boolean 62 * 63 * @link http://wiki.developers.facebook.com/index.php/Feed.publishStoryToUser 64 * @link http://wiki.developers.facebook.com/index.php/PublishActionOfUser_vs._PublishStoryToUser 65 */ 66 public function publishStoryToUser($title, 67 $body = '', 68 array $images = array()) 69 { 70 $args = array( 71 'title' => $title, 72 'session_key' => $this->sessionKey 73 ); 74 75 if (strlen($body)) { 76 $args['body'] = $body; 77 } 78 79 if (count($images)) { 80 // Facebook only allows four images so don't send more than that. 81 $cnt = count($images); 82 if ($cnt > 4) { 83 $cnt = 4; 84 } 85 86 for ($i = 0 ; $i < $cnt ; $i++) { 87 $n = ($i + 1); 88 $args['image_' . $n] = $images[$i]['src']; 89 if (isset($images[$i]['href'])) { 90 $args['image_' . $n . '_link'] = $images[$i]['href']; 91 } else { 92 $args['image_' . $n . '_link'] = $images[$i]['src']; 93 } 94 } 95 } 96 97 $result = $this->callMethod('feed.publishStoryToUser', $args); 98 $check = intval((string)$result->feed_publishStoryToUser_response_elt); 99 return ($check == 1); 100 } 101 102 /** 103 * Publish an action to a user's feed 104 * 105 * An action differs from a story in that a user's action is sent to all 106 * of that user's friends as well. 107 * 108 * The $images array should be a numerically indexed array of arrays, where 109 * each image has two keys: src and href. The src is the full URI of the 110 * image and the href is the link of that image. 111 * 112 * <code> 113 * <?php 114 * $images = array( 115 * array('src' => 'http://example.com/images1.jpg', 116 * 'href' => 'http://example.com/images.php?image=1'), 117 * array('src' => 'http://example.com/images2.jpg', 118 * 'href' => 'http://example.com/images.php?image=2'), 119 * array('src' => 'http://example.com/images3.jpg', 120 * 'href' => 'http://example.com/images.php?image=3') 121 * ); 122 * ?> 123 * </code> 124 * 125 * @param string $title FBML to post as story title 126 * @param string $body FBML to post as story body 127 * @param array $images Images to post to story entry 128 * 129 * @return boolean 130 * 131 * @link http://wiki.developers.facebook.com/index.php/Feed.publishActionOfUser 132 * @link http://wiki.developers.facebook.com/index.php/PublishActionOfUser_vs._PublishStoryToUser 133 */ 134 public function publishActionOfUser($title, 135 $body = '', 136 array $images = array()) 137 { 138 $args = array( 139 'title' => $title, 140 'session_key' => $this->sessionKey 141 ); 142 143 if (strlen($body)) { 144 $args['body'] = $body; 145 } 146 147 if (count($images)) { 148 // Facebook only allows four images so don't send more than that. 149 $cnt = count($images); 150 if ($cnt > 4) { 151 $cnt = 4; 152 } 153 154 for ($i = 0 ; $i < $cnt ; $i++) { 155 $n = ($i + 1); 156 $args['image_' . $n] = $images[$i]['src']; 157 if (isset($images[$i]['href'])) { 158 $args['image_' . $n . '_link'] = $images[$i]['href']; 159 } else { 160 $args['image_' . $n . '_link'] = $images[$i]['src']; 161 } 162 } 163 } 164 165 $result = $this->callMethod('feed.publishActionOfUser', $args); 166 $check = intval((string)$result->feed_publishActionOfUser_response_elt); 167 return ($check == 1); 168 } 169 170 /** 171 * Publish a templatized action to a user's feed 172 * 173 * An action differs from a story in that a user's action is sent to all 174 * of that user's friends as well. 175 * 176 * An templatized story publishes News Feed stories to the friends of that user. 177 * These stories or more likely to appear to the friends of that user depending 178 * upon a variety of factors, such as the closeness of the relationship between 179 * the users, the interaction data facebook has about that particular story type, 180 * and the quality of the content in the story/on the linked page. 181 * http://wiki.developers.facebook.com/index.php/FeedRankingFAQ 182 * 183 * The $images array should be a numerically indexed array of arrays, where 184 * each image has two keys: src and href. The src is the full URI of the 185 * image and the href is the link of that image. 186 * 187 * <code> 188 * <?php 189 * $images = array( 190 * array('src' => 'http://example.com/images1.jpg', 191 * 'href' => 'http://example.com/images.php?image=1'), 192 * array('src' => 'http://example.com/images2.jpg', 193 * 'href' => 'http://example.com/images.php?image=2'), 194 * array('src' => 'http://example.com/images3.jpg', 195 * 'href' => 'http://example.com/images.php?image=3') 196 * ); 197 * ?> 198 * </code> 199 * 200 * @param string $titleTemplate FBML to post as the title, must contain {actor} 201 * @param array $feedData Array containing optional Feed template, data, and/or actor id 202 * @param array $images Images to post to story entry 203 * 204 * @return boolean 205 * 206 * @author Jeff Hodsdon <jeffhodsdon@gmail.com> 207 * @link http://wiki.developers.facebook.com/index.php/Feed.publishTemplatizedAction 208 */ 209 public function publishTemplatizedAction($titleTemplate, 210 array $feedData = array(), 211 array $images = array()) 212 { 213 $args = array( 214 'title_template' => $titleTemplate, 215 'session_key' => $this->sessionKey 216 ); 217 218 static $options = array('title_data', 'body_template', 'body_data', 219 'body_general', 'page_actor_id'); 220 221 foreach ($options as $opt) { 222 if (isset($feedData[$opt]) && strlen($feedData[$opt])) { 223 $args[$opt] = $feedData[$opt]; 224 } 225 } 226 227 if (count($images)) { 228 // Facebook only allows four images so don't send more than that. 229 $cnt = count($images); 230 if ($cnt > 4) { 231 $cnt = 4; 232 } 233 234 for ($i = 0 ; $i < $cnt ; $i++) { 235 $n = ($i + 1); 236 $args['image_' . $n] = $images[$i]['src']; 237 if (isset($images[$i]['href'])) { 238 $args['image_' . $n . '_link'] = $images[$i]['href']; 239 } else { 240 $args['image_' . $n . '_link'] = $images[$i]['src']; 241 } 242 } 243 } 244 245 $result = $this->callMethod('feed.publishTemplatizedAction', $args); 246 return (intval((string)$result) == 1); 247 } 248 249 /** 250 * Builds a template bundle around the specified templates, registers them 251 * on Facebook, and responds with a template bundle ID that can be used 252 * to identify your template bundle to other Feed-related API calls. 253 * 254 * A template bundle consists of: 255 * - an array of one line story templates 256 * - an array of short story templates 257 * - a single full story template 258 * 259 * Each array consists of one or more templates, and each template consists 260 * of one or more tokens (for the story actor, friends, items, and so 261 * forth), some static text, and some FBML. Tokens must be wrapped in curly 262 * braces and asterisks, as in {*actor*}. The {*actor*} token must appear 263 * at the beginning of all one line templates and at the beginning of short 264 * and full template story titles. 265 * 266 * The order of templates in an array is very important. In general, the 267 * most flexible template should be first in the array. The most flexible 268 * template has the most tokens in it. The first template will always be used 269 * for feed stories. The last one-line template in the array must be the 270 * least flexible of all the template in the bundle. Thus, it should include 271 * only tokens that are a strict subset of all other tokens. 272 * 273 * When considering these templates, the first template makes for the best 274 * story, but the last template has the highest aggregation potential. When 275 * you publish a story using feed.publishUserAction, you're posting the 276 * first version of the story to a user's Mini-Feed, and you're posting one 277 * of three different stories to that users friends' News Feeds. 278 * 279 * Short story each consist of two parts, a template title and a template 280 * body. Short stories should be passed as an array of short stories, 281 * with each element being an array containing the keys 'template_title' 282 * and 'template_body' 283 * 284 * Full story templates should be passed as an array containing keys 285 * 'template_title' and 'template_body' 286 * 287 * Action links @see http://wiki.developers.facebook.com/index.php/Action_Links 288 * 289 * @access public 290 * @param array $oneLineStoryTpls array of one-line story templates 291 * @param array $shortStoryTpls optional array of short story templates 292 * @param array $fullStoryTemplate optional full story template 293 * @param array $actionLinks optional array of actoin link records 294 * @return string template bundle ID of newly registered bundle 295 * @link http://wiki.developers.facebook.com/index.php/Feed.registerTemplateBundle 296 * @author Matthew Fonda <matthewfonda@gmail.com> 297 */ 298 public function registerTemplateBundle(array $oneLineStoryTpls, 299 array $shortStoryTpls = array(), 300 array $fullStoryTpl = array(), 301 array $actionLinks = array()) 302 { 303 $args = array(); 304 if (count($oneLineStoryTpls)) { 305 $args['one_line_story_templates'] = json_encode($oneLineStoryTpls); 306 } else { 307 throw new Services_Facebook_Exception( 308 'Feed.registerTemplateBundle requires at least one one-line story template' 309 ); 310 } 311 312 if (count($shortStoryTpls)) { 313 $args['short_story_templates'] = json_encode($shortStoryTpls); 314 } 315 316 if (isset($fullStoryTpl['template_title'], $fullStoryTpl['template_body'])) { 317 $args['full_story_template'] = json_encode($fullStoryTpl); 318 } 319 320 if (count($actionLinks)) { 321 $args['action_links'] = json_encode($actionLinks); 322 } 323 324 $result = $this->callMethod('feed.registerTemplateBundle', $args); 325 return (float) (string)$result; 326 } 327 328 /** 329 * Retrieves the full list of all template bundles registered by the 330 * requesting application. This does not include any template bundles 331 * previously deactivated via calls to feed.deactivateTemplateBundle 332 * 333 * @access public 334 * @return SimpleXMLElement SimpleXMLElement containing templates 335 * @link http://wiki.developers.facebook.com/index.php/Feed.getRegisteredTemplateBundles 336 * @author Matthew Fonda <matthewfonda@gmail.com> 337 */ 338 public function getRegisteredTemplateBundles() 339 { 340 return $this->callMethod('feed.getRegisteredTemplateBundles'); 341 } 342 343 /** 344 * Returns information about a specified template bundle previously 345 * registered by the requesting application. The result is returned 346 * as a SimpleXMLElement. 347 * 348 * @access public 349 * @param int $id ID of template bundle 350 * @return SimpleXMLElement SimpleXMLElement representing the bundle 351 * @link http://wiki.developers.facebook.com/index.php/Feed.getRegisteredTemplateBundleByID 352 * @author Matthew Fonda <matthewfonda@gmail.com> 353 */ 354 public function getRegisteredTemplateBundleByID($id) 355 { 356 $args = array('template_bundle_id' => $id); 357 return $this->callMethod('feed.getRegisteredTemplateBundleByID', $args); 358 } 359 360 /** 361 * Deactivates a previously registered template bundle. Once a template 362 * bundle has been deactivated, it can no longer be used to publish stories 363 * via feed.publishUserAction. Stories published agaisnt the template 364 * bundle prior to its deactivation are still valid and will show up in the 365 * Mini-Feed and News Feed. The response is true if and only if the template 366 * bundle, identified by $id, is an active template bundle owned by the 367 * requesting application, and is false otherwise. 368 * 369 * @access public 370 * @param int $id ID of template bundle to deactivate 371 * @return boolean 372 * @link http://wiki.developers.facebook.com/index.php/Feed.deactivateTemplateBundleByID 373 * @author Matthew Fonda <matthewfonda@gmail.com> 374 */ 375 public function deactivateTemplateBundleByID($id) 376 { 377 $args = array('template_bundle_id' => $id); 378 $result = $this->callMethod('feed.deactivateTemplateBundleByID', $args); 379 return (intval($result) == 1); 380 } 381 382 /** 383 * Publishes a story on behald of the user owning the session, using the 384 * specified template bundle. This method requires an active session key 385 * in order to be called. This method returns true if all succeeds, and 386 * false of the user never authorized the application to publish to his or 387 * her Mini-Feed. 388 * 389 * This method should be passed a template bundle ID to use, and an array 390 * of template data whose keys are the tokens to replace, and values are 391 * the desired replacement. 'actor' and 'target' are special tokens and 392 * should not be included in this array. If one or more of the templates 393 * include tokens other than 'actor' and 'targets', then this array is 394 * required. This array can also include exactly one of the following keys: 395 * 'images', 'flash', 'mp3', or 'video'. 396 * 397 * If 'images' is passed, it should map to an array of up to four images, 398 * and each array should contain a key 'src', and optionally 'href' 399 * 400 * If 'flash' is passed, it should map to an array containing two required 401 * keys: 'swfsrc', which is the URL of the flash object to be rendered, and 402 * 'imgsrc', which is the URL of an image to be displayed until the users 403 * clicks the flash object. Optionally, the 'flash' array can contain 'width' 404 * and 'height'. The height must be an integer between 30 and 100 (inclusive), 405 * and the width must be either 100, 110, or 130. 406 * 407 * If 'mp3' is passed, it must contain a single required field, 'src', and 408 * can optionally contain 'title', 'artist', and 'album' 409 * 410 * If 'video' is passed, it must contain two required fields: 'video_src' 411 * and 'preview_img'. The video array can also contain the following 412 * optional fields: 'video_title', 'video_link', and 'video_type'. 413 * 414 * If the template in questions contains a 'target' token, the userIDs 415 * of the target should be passed as an array, $targetIDs. 416 * 417 * @access public 418 * @param int $templateBundleID ID of template bundle to use 419 * @param array $templateData array of template data 420 * @param array $targetIDs array of target IDs 421 * @param string $bodyGeneral additional markup that extends the 422 * body of a short story 423 * @return boolean 424 * @link http://wiki.developers.facebook.com/index.php/Feed.publishUserAction 425 * @author Matthew Fonda <matthewfonda@gmail.com> 426 */ 427 public function publishUserAction($templateBundleID, 428 array $templateData = array(), 429 array $targetIDs = array(), 430 $bodyGeneral = '' 431 ) 432 { 433 $args = array('session_key' => $this->sessionKey, 434 'template_bundle_id' => $templateBundleID 435 ); 436 if (count($templateData)) { 437 $args['template_data'] = json_encode($templateData); 438 } 439 440 if (count($targetIDs)) { 441 $args['target_ids'] = implode(',', $targetIDs); 442 } 443 444 if (strlen($bodyGeneral)) { 445 $args['body_general'] = $bodyGeneral; 446 } 447 448 $result = $this->callMethod('feed.publishUserAction', $args); 449 return (intval($result->feed_publishUserAction_response_elt) == 1); 450 } 451 452} 453 454?> 455