ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/facebook/trunk/facebookapi_php5_restlib.php
(Generate patch)

Comparing facebook/trunk/facebookapi_php5_restlib.php (file contents):
Revision 956 by douglas, 2007-10-11T02:45:01-07:00 vs.
Revision 1058 by douglas, 2008-06-25T02:40:10-07:00

# Line 6 | Line 6
6   # Douglas Thrift
7   #
8   # $Id$
9 +
10 + // Copyright 2004-2008 Facebook. All Rights Reserved.
11   //
12   // +---------------------------------------------------------------------------+
13   // | Facebook Platform PHP5 client                                             |
14   // +---------------------------------------------------------------------------+
15 < // | Copyright (c) 2007 Facebook, Inc.                                         |
15 > // | Copyright (c) 2007-2008 Facebook, Inc.                                    |
16   // | All rights reserved.                                                      |
17   // |                                                                           |
18   // | Redistribution and use in source and binary forms, with or without        |
# Line 45 | Line 47 | class FacebookRestClient {
47    public $friends_list; // to save making the friends.get api call, this will get prepopulated on canvas pages
48    public $added;        // to save making the users.isAppAdded api call, this will get prepopulated on canvas pages
49    public $json;
50 +  public $batch_mode;
51 +  private $batch_queue;
52 +  private $call_as_apikey;
53 +
54 +  const BATCH_MODE_DEFAULT = 0;
55 +  const BATCH_MODE_SERVER_PARALLEL = 0;
56 +  const BATCH_MODE_SERIAL_ONLY = 2;
57  
58    /**
59     * Create the client.
60 <   * @param string $session_key if you haven't gotten a session key yet, leave
61 <   *                            this as null and then set it later by just
62 <   *                            directly accessing the $session_key member
60 >   * @param string $session_key if you haven't gotten a session key yet, leave
61 >   *                            this as null and then set it later by just
62 >   *                            directly accessing the $session_key member
63     *                            variable.
64     */
65    public function __construct($api_key, $secret, $session_key=null) {
66      $this->secret       = $secret;
67      $this->session_key  = $session_key;
68      $this->api_key      = $api_key;
69 +    $this->batch_mode = FacebookRestClient::BATCH_MODE_DEFAULT;
70      $this->last_call_id = 0;
71 +    $this->call_as_apikey = '';
72      $this->server_addr  = Facebook::get_facebook_url('api') . '/restserver.php';
73 <    if ($GLOBALS['facebook_config']['debug']) {
73 >    if (!empty($GLOBALS['facebook_config']['debug'])) {
74        $this->cur_id = 0;
75        ?>
76   <script type="text/javascript">
77   var types = ['params', 'xml', 'php', 'sxml'];
78 + function getStyle(elem, style) {
79 +  if (elem.getStyle) {
80 +    return elem.getStyle(style);
81 +  } else {
82 +    return elem.style[style];
83 +  }
84 + }
85 + function setStyle(elem, style, value) {
86 +  if (elem.setStyle) {
87 +    elem.setStyle(style, value);
88 +  } else {
89 +    elem.style[style] = value;
90 +  }
91 + }
92   function toggleDisplay(id, type) {
93 <  for each (var t in types) {
94 <    if (t != type || document.getElementById(t + id).style.display == 'block') {
95 <      document.getElementById(t + id).style.display = 'none';
96 <    } else {
97 <      document.getElementById(t + id).style.display = 'block';
93 >  for (var i = 0; i < types.length; i++) {
94 >    var t = types[i];
95 >    var pre = document.getElementById(t + id);
96 >    if (pre) {
97 >      if (t != type || getStyle(pre, 'display') == 'block') {
98 >        setStyle(pre, 'display', 'none');
99 >      } else {
100 >        setStyle(pre, 'display', 'block');
101 >      }
102      }
103    }
104    return false;
# Line 79 | Line 108 | function toggleDisplay(id, type) {
108      }
109    }
110  
111 +
112 +  /**
113 +   * Start a batch operation.
114 +   */
115 +  public function begin_batch() {
116 +    if($this->batch_queue !== null)
117 +    {
118 +      throw new FacebookRestClientException(FacebookAPIErrorCodes::API_EC_BATCH_ALREADY_STARTED,
119 +      FacebookAPIErrorCodes::$api_error_descriptions[FacebookAPIErrorCodes::API_EC_BATCH_ALREADY_STARTED]);
120 +    }
121 +
122 +    $this->batch_queue = array();
123 +  }
124 +
125 +  /*
126 +   * End current batch operation
127 +   */
128 +  public function end_batch() {
129 +    if($this->batch_queue === null) {
130 +      throw new FacebookRestClientException(FacebookAPIErrorCodes::API_EC_BATCH_NOT_STARTED,
131 +      FacebookAPIErrorCodes::$api_error_descriptions[FacebookAPIErrorCodes::API_EC_BATCH_NOT_STARTED]);
132 +    }
133 +
134 +    $this->execute_server_side_batch();
135 +
136 +    $this->batch_queue = null;
137 +  }
138 +
139 +
140 +  private function execute_server_side_batch() {
141 +
142 +
143 +    $item_count = count($this->batch_queue);
144 +    $method_feed = array();
145 +    foreach($this->batch_queue as $batch_item) {
146 +      $method_feed[] = $this->create_post_string($batch_item['m'], $batch_item['p']);
147 +    }
148 +
149 +    $method_feed_json = json_encode($method_feed);
150 +
151 +    $serial_only = $this->batch_mode == FacebookRestClient::BATCH_MODE_SERIAL_ONLY ;
152 +    $params = array('method_feed' => $method_feed_json, 'serial_only' => $serial_only);
153 +    if ($this->call_as_apikey) {
154 +      $params['call_as_apikey'] = $this->call_as_apikey;
155 +    }
156 +
157 +    $xml = $this->post_request('batch.run', $params);
158 +
159 +    $result = $this->convert_xml_to_result($xml, 'batch.run', $params);
160 +
161 +
162 +    if (is_array($result) && isset($result['error_code'])) {
163 +      throw new FacebookRestClientException($result['error_msg'], $result['error_code']);
164 +    }
165 +
166 +    for($i = 0; $i < $item_count; $i++) {
167 +      $batch_item = $this->batch_queue[$i];
168 +      $batch_item_result_xml = $result[$i];
169 +      $batch_item_result = $this->convert_xml_to_result($batch_item_result_xml, $batch_item['m'], $batch_item['p']);
170 +
171 +      if (is_array($batch_item_result) && isset($batch_item_result['error_code'])) {
172 +        throw new FacebookRestClientException($batch_item_result['error_msg'], $batch_item_result['error_code']);
173 +      }
174 +      $batch_item['r'] = $batch_item_result;
175 +    }
176 +  }
177 +
178 +  public function begin_permissions_mode($permissions_apikey) {
179 +    $this->call_as_apikey = $permissions_apikey;
180 +  }
181 +
182 +  public function end_permissions_mode() {
183 +    $this->call_as_apikey = '';
184 +  }
185 +
186    /**
187     * Returns the session information available after current user logs in.
188 <   * @param string $auth_token the token returned by auth_createToken or
188 >   * @param string $auth_token the token returned by auth_createToken or
189     *  passed back to your callback_url.
190 +   * @param bool   $generate_session_secret  whether the session returned should include a session secret
191 +   *
192     * @return assoc array containing session_key, uid
193     */
194 <  public function auth_getSession($auth_token) {
195 <    $result = $this->call_method('facebook.auth.getSession', array('auth_token'=>$auth_token));
196 <    $this->session_key = $result['session_key'];
197 <    if (isset($result['secret']) && $result['secret']) {
194 >  public function auth_getSession($auth_token, $generate_session_secret=false) {
195 >    //Check if we are in batch mode
196 >    if($this->batch_queue === null) {
197 >      $result = $this->call_method('facebook.auth.getSession',
198 >          array('auth_token' => $auth_token, 'generate_session_secret' => $generate_session_secret));
199 >      $this->session_key = $result['session_key'];
200 >
201 >    if (!empty($result['secret']) && !$generate_session_secret) {
202        // desktop apps have a special secret
203        $this->secret = $result['secret'];
204      }
205 <    return $result;
205 >      return $result;
206 >    }
207 >  }
208 >
209 >  /**
210 >   * Generates a session specific secret. This is for integration with client-side API calls, such as the
211 >   * JS library.
212 >   * @error API_EC_PARAM_SESSION_KEY
213 >   *        API_EC_PARAM_UNKNOWN
214 >   * @return session secret for the current promoted session
215 >   */
216 >  public function auth_promoteSession() {
217 >      return $this->call_method('facebook.auth.promoteSession', array());
218 >  }
219 >
220 >  /**
221 >   * Expires the session that is currently being used.  If this call is successful, no further calls to the
222 >   * API (which require a session) can be made until a valid session is created.
223 >   *
224 >   * @return bool  true if session expiration was successful, false otherwise
225 >   */
226 >  public function auth_expireSession() {
227 >      return $this->call_method('facebook.auth.expireSession', array());
228    }
229  
230    /**
231     * Returns events according to the filters specified.
232 <   * @param int $uid Optional: User associated with events.  
232 >   * @param int $uid Optional: User associated with events.
233     *   A null parameter will default to the session user.
234     * @param array $eids Optional: Filter by these event ids.
235     *   A null parameter will get all events for the user.
236 <   * @param int $start_time Optional: Filter with this UTC as lower bound.  
236 >   * @param int $start_time Optional: Filter with this UTC as lower bound.
237     *   A null or zero parameter indicates no lower bound.
238 <   * @param int $end_time Optional: Filter with this UTC as upper bound.
238 >   * @param int $end_time Optional: Filter with this UTC as upper bound.
239     *   A null or zero parameter indicates no upper bound.
240     * @param string $rsvp_status Optional: Only show events where the given uid
241     *   has this rsvp status.  This only works if you have specified a value for
# Line 111 | Line 243 | function toggleDisplay(id, type) {
243     *   rsvp status when filtering.
244     * @return array of events
245     */
246 <  public function events_get($uid, $eids, $start_time, $end_time, $rsvp_status) {
246 >  public function &events_get($uid, $eids, $start_time, $end_time, $rsvp_status) {
247      return $this->call_method('facebook.events.get',
248          array(
249          'uid' => $uid,
250          'eids' => $eids,
251 <        'start_time' => $start_time,
251 >        'start_time' => $start_time,
252          'end_time' => $end_time,
253          'rsvp_status' => $rsvp_status));
254    }
# Line 127 | Line 259 | function toggleDisplay(id, type) {
259     * @return assoc array of four membership lists, with keys 'attending',
260     *  'unsure', 'declined', and 'not_replied'
261     */
262 <  public function events_getMembers($eid) {
262 >  public function &events_getMembers($eid) {
263      return $this->call_method('facebook.events.getMembers',
264        array('eid' => $eid));
265    }
# Line 139 | Line 271 | function toggleDisplay(id, type) {
271     * @param string $query the query to evaluate
272     * @return generalized array representing the results
273     */
274 <  public function fql_query($query) {
274 >  public function &fql_query($query) {
275      return $this->call_method('facebook.fql.query',
276        array('query' => $query));
277    }
278  
279 <  public function feed_publishStoryToUser($title, $body,
279 >  public function &feed_publishStoryToUser($title, $body,
280                                            $image_1=null, $image_1_link=null,
281                                            $image_2=null, $image_2_link=null,
282                                            $image_3=null, $image_3_link=null,
# Line 161 | Line 293 | function toggleDisplay(id, type) {
293              'image_4' => $image_4,
294              'image_4_link' => $image_4_link));
295    }
296 <                                          
297 <  public function feed_publishActionOfUser($title, $body,
296 >
297 >  public function &feed_publishActionOfUser($title, $body,
298                                             $image_1=null, $image_1_link=null,
299                                             $image_2=null, $image_2_link=null,
300                                             $image_3=null, $image_3_link=null,
# Line 180 | Line 312 | function toggleDisplay(id, type) {
312              'image_4_link' => $image_4_link));
313    }
314  
315 <  public function feed_publishTemplatizedAction($actor_id, $title_template, $title_data,
315 >  public function &feed_publishTemplatizedAction($title_template, $title_data,
316                                                  $body_template, $body_data, $body_general,
317                                                  $image_1=null, $image_1_link=null,
318                                                  $image_2=null, $image_2_link=null,
319                                                  $image_3=null, $image_3_link=null,
320                                                  $image_4=null, $image_4_link=null,
321 <                                                $target_ids='') {
321 >                                                $target_ids='', $page_actor_id=null) {
322      return $this->call_method('facebook.feed.publishTemplatizedAction',
323 <      array('actor_id' => $actor_id,
192 <            'title_template' => $title_template,
323 >      array('title_template' => $title_template,
324              'title_data' => is_array($title_data) ? json_encode($title_data) : $title_data,
325              'body_template' => $body_template,
326              'body_data' => is_array($body_data) ? json_encode($body_data) : $body_data,
# Line 202 | Line 333 | function toggleDisplay(id, type) {
333              'image_3_link' => $image_3_link,
334              'image_4' => $image_4,
335              'image_4_link' => $image_4_link,
336 <            'target_ids' => $target_ids));
336 >            'target_ids' => $target_ids,
337 >            'page_actor_id' => $page_actor_id));
338    }
339  
340    /**
# Line 212 | Line 344 | function toggleDisplay(id, type) {
344     * @param array $uids2: array of ids (id_A, id_B,...) of SAME length X
345     * @return array of uid pairs with bool, true if pair are friends, e.g.
346     *   array( 0 => array('uid1' => id_1, 'uid2' => id_A, 'are_friends' => 1),
347 <   *          1 => array('uid1' => id_2, 'uid2' => id_B, 'are_friends' => 0)
347 >   *          1 => array('uid1' => id_2, 'uid2' => id_B, 'are_friends' => 0)
348     *         ...)
349     */
350 <  public function friends_areFriends($uids1, $uids2) {
350 >  public function &friends_areFriends($uids1, $uids2) {
351      return $this->call_method('facebook.friends.areFriends',
352          array('uids1'=>$uids1, 'uids2'=>$uids2));
353    }
354 <  
354 >
355    /**
356     * Returns the friends of the current session user.
357     * @return array of friends
358     */
359 <  public function friends_get() {
359 >  public function &friends_get() {
360      if (isset($this->friends_list)) {
361        return $this->friends_list;
362      }
363      return $this->call_method('facebook.friends.get', array());
364    }
365 <  
365 >
366    /**
367     * Returns the friends of the session user, who are also users
368     * of the calling application.
369     * @return array of friends
370     */
371 <  public function friends_getAppUsers() {
371 >  public function &friends_getAppUsers() {
372      return $this->call_method('facebook.friends.getAppUsers', array());
373    }
374  
375    /**
376     * Returns groups according to the filters specified.
377 <   * @param int $uid Optional: User associated with groups.  
377 >   * @param int $uid Optional: User associated with groups.
378     *  A null parameter will default to the session user.
379     * @param array $gids Optional: group ids to query.
380     *   A null parameter will get all groups for the user.
381     * @return array of groups
382     */
383 <  public function groups_get($uid, $gids) {
383 >  public function &groups_get($uid, $gids) {
384      return $this->call_method('facebook.groups.get',
385          array(
386          'uid' => $uid,
# Line 258 | Line 390 | function toggleDisplay(id, type) {
390    /**
391     * Returns the membership list of a group
392     * @param int $gid : Group id
393 <   * @return assoc array of four membership lists, with keys
393 >   * @return assoc array of four membership lists, with keys
394     *  'members', 'admins', 'officers', and 'not_replied'
395     */
396 <  public function groups_getMembers($gid) {
396 >  public function &groups_getMembers($gid) {
397      return $this->call_method('facebook.groups.getMembers',
398        array('gid' => $gid));
399    }
400  
401    /**
402 +   * Returns cookies according to the filters specified.
403 +   * @param int $uid Required: User for which the cookies are needed.
404 +   * @param string $name Optional:
405 +   *   A null parameter will get all cookies for the user.
406 +   * @return array of cookies
407 +   */
408 +  public function data_getCookies($uid, $name) {
409 +    return $this->call_method('facebook.data.getCookies',
410 +        array(
411 +        'uid' => $uid,
412 +        'name' => $name));
413 +  }
414 +
415 +  /**
416 +   * Sets cookies according to the params specified.
417 +   * @param int $uid Required: User for which the cookies are needed.
418 +   * @param string $name Required: name of the cookie
419 +   * @param string $value Optional if expires specified and is in the past
420 +   * @param int$expires Optional
421 +   * @param string $path Optional
422 +   *
423 +   * @return bool
424 +   */
425 +  public function data_setCookie($uid, $name, $value, $expires, $path) {
426 +    return $this->call_method('facebook.data.setCookie',
427 +        array(
428 +        'uid' => $uid,
429 +        'name' => $name,
430 +        'value' => $value,
431 +        'expires' => $expires,
432 +        'path' => $path));
433 +  }
434 +
435 +  /**
436 +   * Permissions API
437 +   */
438 +
439 +  /**
440 +   * Checks API-access granted by self to the specified application
441 +   * @param string $permissions_apikey: Required
442 +   *
443 +   * @return array: API methods/namespaces which are allowed access
444 +   */
445 +  public function permissions_checkGrantedApiAccess($permissions_apikey) {
446 +    return $this->call_method('facebook.permissions.checkGrantedApiAccess',
447 +        array(
448 +        'permissions_apikey' => $permissions_apikey));
449 +  }
450 +
451 +  /**
452 +   * Checks API-access granted to self by the specified application
453 +   * @param string $permissions_apikey: Required
454 +   *
455 +   * @return array: API methods/namespaces which are allowed access
456 +   */
457 +  public function permissions_checkAvailableApiAccess($permissions_apikey) {
458 +    return $this->call_method('facebook.permissions.checkAvailableApiAccess',
459 +        array(
460 +        'permissions_apikey' => $permissions_apikey));
461 +  }
462 +
463 +  /**
464 +   * Grant API-access to the specified methods/namespaces to the specified application
465 +   * @param string $permissions_apikey: Required
466 +   * @param array(string) : Optional: API methods/namespaces to be allowed
467 +   *
468 +   * @return array: API methods/namespaces which are allowed access
469 +   */
470 +  public function permissions_grantApiAccess($permissions_apikey, $method_arr) {
471 +    return $this->call_method('facebook.permissions.grantApiAccess',
472 +        array(
473 +        'permissions_apikey' => $permissions_apikey,
474 +        'method_arr' => $method_arr));
475 +  }
476 +
477 +  /**
478 +   * Revoke API-access granted to the specified application
479 +   * @param string $permissions_apikey: Required
480 +   *
481 +   * @return bool
482 +   */
483 +  public function permissions_revokeApiAccess($permissions_apikey) {
484 +    return $this->call_method('facebook.permissions.revokeApiAccess',
485 +        array(
486 +        'permissions_apikey' => $permissions_apikey));
487 +  }
488 +
489 +  /**
490     * Returns the outstanding notifications for the session user.
491 <   * @return assoc array of
492 <   *  notification count objects for 'messages', 'pokes' and 'shares',
491 >   * @return assoc array of
492 >   *  notification count objects for 'messages', 'pokes' and 'shares',
493     *  a uid list of 'friend_requests', a gid list of 'group_invites',
494     *  and an eid list of 'event_invites'
495     */
496 <  public function notifications_get() {
496 >  public function &notifications_get() {
497      return $this->call_method('facebook.notifications.get', array());
498    }
499  
500    /**
501 <   * Sends an email notification to the specified user.
502 <   * @return string url which you should send the logged in user to to finalize the message.
501 >   * Sends a notification to the specified users.
502 >   * @return (nothing)
503     */
504 <  public function notifications_send($to_ids, $notification, $email='') {
504 >  public function &notifications_send($to_ids, $notification) {
505      return $this->call_method('facebook.notifications.send',
506 <                              array('to_ids' => $to_ids, 'notification' => $notification, 'email' => $email));
506 >                              array('to_ids' => $to_ids, 'notification' => $notification));
507 >  }
508 >
509 >  /**
510 >   * Sends an email to the specified user of the application.
511 >   * @param array $recipients : id of the recipients
512 >   * @param string $subject : subject of the email
513 >   * @param string $text : (plain text) body of the email
514 >   * @param string $fbml : fbml markup if you want an html version of the email
515 >   * @return comma separated list of successful recipients
516 >   */
517 >  public function &notifications_sendEmail($recipients, $subject, $text, $fbml) {
518 >    return $this->call_method('facebook.notifications.sendEmail',
519 >                              array('recipients' => $recipients,
520 >                                    'subject' => $subject,
521 >                                    'text' => $text,
522 >                                    'fbml' => $fbml));
523 >  }
524 >
525 >  /**
526 >   * Returns the requested info fields for the requested set of pages
527 >   * @param array $page_ids an array of page ids
528 >   * @param array $fields an array of strings describing the info fields desired
529 >   * @param int $uid   Optionally, limit results to pages of which this user is a fan.
530 >   * @param string type  limits results to a particular type of page.
531 >   * @return array of pages
532 >   */
533 >  public function &pages_getInfo($page_ids, $fields, $uid, $type) {
534 >    return $this->call_method('facebook.pages.getInfo', array('page_ids' => $page_ids, 'fields' => $fields, 'uid' => $uid, 'type' => $type));
535 >  }
536 >
537 >  /**
538 >   * Returns true if logged in user is an admin for the passed page
539 >   * @param int $page_id target page id
540 >   * @return boolean
541 >   */
542 >  public function &pages_isAdmin($page_id) {
543 >    return $this->call_method('facebook.pages.isAdmin', array('page_id' => $page_id));
544 >  }
545 >
546 >  /**
547 >   * Returns whether or not the page corresponding to the current session object has the app installed
548 >   * @return boolean
549 >   */
550 >  public function &pages_isAppAdded() {
551 >    if (isset($this->added)) {
552 >      return $this->added;
553 >    }
554 >    return $this->call_method('facebook.pages.isAppAdded', array());
555    }
556  
557    /**
558 <   * Sends a request to the specified user (e.g. "you have 1 event invitation")
559 <   * @param array $to_ids   user ids to receive the request (must be friends with sender, capped at 10)
560 <   * @param string $type    type of request, e.g. "event" (as in "You have an event invitation.")
561 <   * @param string $content fbml content of the request.  really stripped down fbml - just
562 <   *                        text/names/links.  also, use the special tag <fb:req-choice url="" label="" />
563 <   *                        to specify the buttons to be included.
564 <   * @param string $image   url of an image to show beside the request
297 <   * @param bool   $invite  whether to call it an "invitation" or a "request"
298 <   * @return string url which you should send the logged in user to to finalize the message.
299 <   */
300 <  public function notifications_sendRequest($to_ids, $type, $content, $image, $invite) {
301 <    return $this->call_method('facebook.notifications.sendRequest',
302 <                              array('to_ids' => $to_ids, 'type' => $type, 'content' => $content,
303 <                                    'image' => $image, 'invite' => $invite));
558 >   * Returns true if logged in user is a fan for the passed page
559 >   * @param int $page_id target page id
560 >   * @param int $uid user to compare.  If empty, the logged in user.
561 >   * @return bool
562 >   */
563 >  public function &pages_isFan($page_id, $uid) {
564 >    return $this->call_method('facebook.pages.isFan', array('page_id' => $page_id, 'uid' => $uid));
565    }
566  
567    /**
568     * Returns photos according to the filters specified.
569     * @param int $subj_id Optional: Filter by uid of user tagged in the photos.
570 <   * @param int $aid Optional: Filter by an album, as returned by
570 >   * @param int $aid Optional: Filter by an album, as returned by
571     *  photos_getAlbums.
572 <   * @param array $pids Optional: Restrict to a list of pids
573 <   * Note that at least one of these parameters needs to be specified, or an
572 >   * @param array $pids Optional: Restrict to a list of pids
573 >   * Note that at least one of these parameters needs to be specified, or an
574     * error is returned.
575     * @return array of photo objects.
576     */
577 <  public function photos_get($subj_id, $aid, $pids) {
578 <    return $this->call_method('facebook.photos.get',
577 >  public function &photos_get($subj_id, $aid, $pids) {
578 >    return $this->call_method('facebook.photos.get',
579        array('subj_id' => $subj_id, 'aid' => $aid, 'pids' => $pids));
580    }
581  
# Line 326 | Line 587 | function toggleDisplay(id, type) {
587     * Note that at least one of the (uid, aids) parameters must be specified.
588     * @returns an array of album objects.
589     */
590 <  public function photos_getAlbums($uid, $aids) {
591 <    return $this->call_method('facebook.photos.getAlbums',
590 >  public function &photos_getAlbums($uid, $aids) {
591 >    return $this->call_method('facebook.photos.getAlbums',
592        array('uid' => $uid,
593              'aids' => $aids));
594    }
# Line 338 | Line 599 | function toggleDisplay(id, type) {
599     * @return array of photo tag objects, with include pid, subject uid,
600     *  and two floating-point numbers (xcoord, ycoord) for tag pixel location
601     */
602 <  public function photos_getTags($pids) {
603 <    return $this->call_method('facebook.photos.getTags',
602 >  public function &photos_getTags($pids) {
603 >    return $this->call_method('facebook.photos.getTags',
604        array('pids' => $pids));
605    }
606  
607 +
608    /**
609     * Returns the requested info fields for the requested set of users
610 <   * @param array $uids an array of user ids
610 >   * @param array $uids an array of user ids
611     * @param array $fields an array of strings describing the info fields desired
612     * @return array of users
613     */
614 <  public function users_getInfo($uids, $fields) {
614 >  public function &users_getInfo($uids, $fields) {
615      return $this->call_method('facebook.users.getInfo', array('uids' => $uids, 'fields' => $fields));
616    }
617  
# Line 357 | Line 619 | function toggleDisplay(id, type) {
619     * Returns the user corresponding to the current session object.
620     * @return integer uid
621     */
622 <  public function users_getLoggedInUser(){
622 >  public function &users_getLoggedInUser() {
623      return $this->call_method('facebook.users.getLoggedInUser', array());
624    }
625  
626 <  
627 <  /**
628 <   * Returns whether or not the user corresponding to the current session object has the app installed
367 <   * @return boolean
626 >  /**
627 >   * Returns whether or not the user corresponding to the current session object has the app installed
628 >   * @return boolean
629     */
630 <  public function users_isAppAdded() {
630 >  public function &users_isAppAdded($uid=null) {
631      if (isset($this->added)) {
632        return $this->added;
633      }
634 <    return $this->call_method('facebook.users.isAppAdded', array());
634 >    return $this->call_method('facebook.users.isAppAdded', array('uid' => $uid));
635    }
636  
637    /**
638     * Sets the FBML for the profile of the user attached to this session
639 <   * @param   string   $markup     The FBML that describes the profile presence of this app for the user
639 >   * @param   string   $markup           The FBML that describes the profile presence of this app for the user
640 >   * @param   int      $uid              The user
641 >   * @param   string   $profile          Profile FBML
642 >   * @param   string   $profile_action   Profile action FBML
643 >   * @param   string   $mobile_profile   Mobile profile FBML
644     * @return  array    A list of strings describing any compile errors for the submitted FBML
645     */
646 <  public function profile_setFBML($markup, $uid = null) {
647 <    return $this->call_method('facebook.profile.setFBML', array('markup' => $markup, 'uid' => $uid));
646 >  function profile_setFBML($markup, $uid = null, $profile='', $profile_action='', $mobile_profile='') {
647 >    return $this->call_method('facebook.profile.setFBML', array('markup' => $markup,
648 >                                                                'uid' => $uid,
649 >                                                                'profile' => $profile,
650 >                                                                'profile_action' => $profile_action,
651 >                                                                'mobile_profile' => $mobile_profile));
652    }
653  
654 <  public function profile_getFBML($uid) {
654 >  public function &profile_getFBML($uid) {
655      return $this->call_method('facebook.profile.getFBML', array('uid' => $uid));
656    }
657  
658 <  public function fbml_refreshImgSrc($url) {
658 >  public function &fbml_refreshImgSrc($url) {
659      return $this->call_method('facebook.fbml.refreshImgSrc', array('url' => $url));
660    }
661  
662 <  public function fbml_refreshRefUrl($url) {
662 >  public function &fbml_refreshRefUrl($url) {
663      return $this->call_method('facebook.fbml.refreshRefUrl', array('url' => $url));
664    }
665  
666 <  public function fbml_setRefHandle($handle, $fbml) {
666 >  public function &fbml_setRefHandle($handle, $fbml) {
667      return $this->call_method('facebook.fbml.setRefHandle', array('handle' => $handle, 'fbml' => $fbml));
668    }
669  
# Line 448 | Line 717 | function toggleDisplay(id, type) {
717     * @param status      'SUCCESS', 'NOT_SUCCESS', or 'DEFAULT'
718     * @return bool       True on success
719     */
720 <  function marketplace_removeListing($listing_id, $status='DEFAULT') {
721 <    return $this->call_method('facebook.marketplace.removeListing',
722 <                              array('listing_id'=>$listing_id,
723 <                                    'status'=>$status));
720 >  function marketplace_removeListing($listing_id, $status='DEFAULT', $uid=null) {
721 >    return $this->call_method('facebook.marketplace.removeListing',
722 >                              array('listing_id'=>$listing_id,
723 >                                    'status'=>$status,
724 >                                    'uid' => $uid));
725    }
726  
727    /**
728     * Create/modify a Marketplace listing for the loggedinuser
729 <   *
729 >   *
730     * @param int              listing_id   The id of a listing to be modified, 0 for a new listing.
731     * @param show_on_profile  bool         Should we show this listing on the user's profile
732 <   * @param attrs            array        An array of the listing data
732 >   * @param listing_attrs    array        An array of the listing data
733     * @return                 int          The listing_id (unchanged if modifying an existing listing)
734     */
735 <  function marketplace_createListing($listing_id, $show_on_profile, $attrs) {
736 <    return $this->call_method('facebook.marketplace.createListing',
737 <                              array('listing_id'=>$listing_id,
738 <                                    'show_on_profile'=>$show_on_profile,
739 <                                    'attrs'=>json_encode($attrs)));
735 >  function marketplace_createListing($listing_id, $show_on_profile, $attrs, $uid=null) {
736 >    return $this->call_method('facebook.marketplace.createListing',
737 >                              array('listing_id'=>$listing_id,
738 >                                    'show_on_profile'=>$show_on_profile,
739 >                                    'listing_attrs'=>json_encode($attrs),
740 >                                    'uid' => $uid));
741    }
742  
743  
744    /////////////////////////////////////////////////////////////////////////////
745    // Data Store API
746 <  
746 >
747    /**
748     * Set a user preference.
749     *
# Line 484 | Line 755 | function toggleDisplay(id, type) {
755     *    API_EC_DATA_QUOTA_EXCEEDED
756     *    API_EC_DATA_UNKNOWN_ERROR
757     */
758 <  public function data_setUserPreference($pref_id, $value) {
758 >  public function &data_setUserPreference($pref_id, $value) {
759      return $this->call_method
760        ('facebook.data.setUserPreference',
761         array('pref_id' => $pref_id,
# Line 495 | Line 766 | function toggleDisplay(id, type) {
766     * Set a user's all preferences for this application.
767     *
768     * @param  values     preferece values in an associative arrays
769 <   * @param  replace    whether to replace all existing preferences or
769 >   * @param  replace    whether to replace all existing preferences or
770     *                    merge into them.
771     * @error
772     *    API_EC_DATA_DATABASE_ERROR
# Line 503 | Line 774 | function toggleDisplay(id, type) {
774     *    API_EC_DATA_QUOTA_EXCEEDED
775     *    API_EC_DATA_UNKNOWN_ERROR
776     */
777 <  public function data_setUserPreferences($values, $replace = false) {
777 >  public function &data_setUserPreferences($values, $replace = false) {
778      return $this->call_method
779        ('facebook.data.setUserPreferences',
780         array('values' => json_encode($values),
# Line 521 | Line 792 | function toggleDisplay(id, type) {
792     *    API_EC_DATA_QUOTA_EXCEEDED
793     *    API_EC_DATA_UNKNOWN_ERROR
794     */
795 <  public function data_getUserPreference($pref_id) {
795 >  public function &data_getUserPreference($pref_id) {
796      return $this->call_method
797        ('facebook.data.getUserPreference',
798         array('pref_id' => $pref_id));
# Line 536 | Line 807 | function toggleDisplay(id, type) {
807     *    API_EC_DATA_QUOTA_EXCEEDED
808     *    API_EC_DATA_UNKNOWN_ERROR
809     */
810 <  public function data_getUserPreferences() {
810 >  public function &data_getUserPreferences() {
811      return $this->call_method
812        ('facebook.data.getUserPreferences',
813         array());
# Line 555 | Line 826 | function toggleDisplay(id, type) {
826     *    API_EC_DATA_QUOTA_EXCEEDED
827     *    API_EC_DATA_UNKNOWN_ERROR
828     */
829 <  public function data_createObjectType($name) {
829 >  public function &data_createObjectType($name) {
830      return $this->call_method
831        ('facebook.data.createObjectType',
832         array('name' => $name));
# Line 574 | Line 845 | function toggleDisplay(id, type) {
845     *    API_EC_DATA_QUOTA_EXCEEDED
846     *    API_EC_DATA_UNKNOWN_ERROR
847     */
848 <  public function data_dropObjectType($obj_type) {
848 >  public function &data_dropObjectType($obj_type) {
849      return $this->call_method
850        ('facebook.data.dropObjectType',
851         array('obj_type' => $obj_type));
# Line 595 | Line 866 | function toggleDisplay(id, type) {
866     *    API_EC_DATA_QUOTA_EXCEEDED
867     *    API_EC_DATA_UNKNOWN_ERROR
868     */
869 <  public function data_renameObjectType($obj_type, $new_name) {
869 >  public function &data_renameObjectType($obj_type, $new_name) {
870      return $this->call_method
871        ('facebook.data.renameObjectType',
872         array('obj_type' => $obj_type,
# Line 617 | Line 888 | function toggleDisplay(id, type) {
888     *    API_EC_DATA_QUOTA_EXCEEDED
889     *    API_EC_DATA_UNKNOWN_ERROR
890     */
891 <  public function data_defineObjectProperty($obj_type, $prop_name, $prop_type){
891 >  public function &data_defineObjectProperty($obj_type, $prop_name, $prop_type) {
892      return $this->call_method
893        ('facebook.data.defineObjectProperty',
894         array('obj_type' => $obj_type,
# Line 627 | Line 898 | function toggleDisplay(id, type) {
898  
899    /**
900     * Remove a previously defined property from an object type.
901 <   *
901 >   *
902     * @param  obj_type      object type's name
903     * @param  prop_name     name of the property to remove
904     * @error
# Line 639 | Line 910 | function toggleDisplay(id, type) {
910     *    API_EC_DATA_QUOTA_EXCEEDED
911     *    API_EC_DATA_UNKNOWN_ERROR
912     */
913 <  public function data_undefineObjectProperty($obj_type, $prop_name) {
913 >  public function &data_undefineObjectProperty($obj_type, $prop_name) {
914      return $this->call_method
915        ('facebook.data.undefineObjectProperty',
916         array('obj_type' => $obj_type,
# Line 648 | Line 919 | function toggleDisplay(id, type) {
919  
920    /**
921     * Rename a previously defined property of an object type.
922 <   *
922 >   *
923     * @param  obj_type      object type's name
924     * @param  prop_name     name of the property to rename
925     * @param  new_name      new name to use
# Line 662 | Line 933 | function toggleDisplay(id, type) {
933     *    API_EC_DATA_QUOTA_EXCEEDED
934     *    API_EC_DATA_UNKNOWN_ERROR
935     */
936 <  public function data_renameObjectProperty($obj_type, $prop_name,
936 >  public function &data_renameObjectProperty($obj_type, $prop_name,
937                                              $new_name) {
938      return $this->call_method
939        ('facebook.data.renameObjectProperty',
# Line 681 | Line 952 | function toggleDisplay(id, type) {
952     *    API_EC_DATA_QUOTA_EXCEEDED
953     *    API_EC_DATA_UNKNOWN_ERROR
954     */
955 <  public function data_getObjectTypes() {
955 >  public function &data_getObjectTypes() {
956      return $this->call_method
957        ('facebook.data.getObjectTypes',
958         array());
# Line 700 | Line 971 | function toggleDisplay(id, type) {
971     *    API_EC_DATA_QUOTA_EXCEEDED
972     *    API_EC_DATA_UNKNOWN_ERROR
973     */
974 <  public function data_getObjectType($obj_type) {
974 >  public function &data_getObjectType($obj_type) {
975      return $this->call_method
976        ('facebook.data.getObjectType',
977         array('obj_type' => $obj_type));
# Line 708 | Line 979 | function toggleDisplay(id, type) {
979  
980    /**
981     * Create a new object.
982 <   *
982 >   *
983     * @param  obj_type      object type's name
984     * @param  properties    (optional) properties to set initially
985     * @return               newly created object's id
# Line 720 | Line 991 | function toggleDisplay(id, type) {
991     *    API_EC_DATA_QUOTA_EXCEEDED
992     *    API_EC_DATA_UNKNOWN_ERROR
993     */
994 <  public function data_createObject($obj_type, $properties = null) {
994 >  public function &data_createObject($obj_type, $properties = null) {
995      return $this->call_method
996        ('facebook.data.createObject',
997         array('obj_type' => $obj_type,
# Line 742 | Line 1013 | function toggleDisplay(id, type) {
1013     *    API_EC_DATA_QUOTA_EXCEEDED
1014     *    API_EC_DATA_UNKNOWN_ERROR
1015     */
1016 <  public function data_updateObject($obj_id, $properties, $replace = false) {
1016 >  public function &data_updateObject($obj_id, $properties, $replace = false) {
1017      return $this->call_method
1018        ('facebook.data.updateObject',
1019         array('obj_id' => $obj_id,
# Line 763 | Line 1034 | function toggleDisplay(id, type) {
1034     *    API_EC_DATA_QUOTA_EXCEEDED
1035     *    API_EC_DATA_UNKNOWN_ERROR
1036     */
1037 <  public function data_deleteObject($obj_id) {
1037 >  public function &data_deleteObject($obj_id) {
1038      return $this->call_method
1039        ('facebook.data.deleteObject',
1040         array('obj_id' => $obj_id));
# Line 781 | Line 1052 | function toggleDisplay(id, type) {
1052     *    API_EC_DATA_QUOTA_EXCEEDED
1053     *    API_EC_DATA_UNKNOWN_ERROR
1054     */
1055 <  public function data_deleteObjects($obj_ids) {
1055 >  public function &data_deleteObjects($obj_ids) {
1056      return $this->call_method
1057        ('facebook.data.deleteObjects',
1058         array('obj_ids' => json_encode($obj_ids)));
# Line 802 | Line 1073 | function toggleDisplay(id, type) {
1073     *    API_EC_DATA_QUOTA_EXCEEDED
1074     *    API_EC_DATA_UNKNOWN_ERROR
1075     */
1076 <  public function data_getObjectProperty($obj_id, $prop_name) {
1076 >  public function &data_getObjectProperty($obj_id, $prop_name) {
1077      return $this->call_method
1078        ('facebook.data.getObjectProperty',
1079         array('obj_id' => $obj_id,
# Line 824 | Line 1095 | function toggleDisplay(id, type) {
1095     *    API_EC_DATA_QUOTA_EXCEEDED
1096     *    API_EC_DATA_UNKNOWN_ERROR
1097     */
1098 <  public function data_getObject($obj_id, $prop_names = null) {
1098 >  public function &data_getObject($obj_id, $prop_names = null) {
1099      return $this->call_method
1100        ('facebook.data.getObject',
1101         array('obj_id' => $obj_id,
# Line 846 | Line 1117 | function toggleDisplay(id, type) {
1117     *    API_EC_DATA_QUOTA_EXCEEDED
1118     *    API_EC_DATA_UNKNOWN_ERROR
1119     */
1120 <  public function data_getObjects($obj_ids, $prop_names = null) {
1120 >  public function &data_getObjects($obj_ids, $prop_names = null) {
1121      return $this->call_method
1122        ('facebook.data.getObjects',
1123         array('obj_ids' => json_encode($obj_ids),
# Line 868 | Line 1139 | function toggleDisplay(id, type) {
1139     *    API_EC_DATA_QUOTA_EXCEEDED
1140     *    API_EC_DATA_UNKNOWN_ERROR
1141     */
1142 <  public function data_setObjectProperty($obj_id, $prop_name,
1142 >  public function &data_setObjectProperty($obj_id, $prop_name,
1143                                           $prop_value) {
1144      return $this->call_method
1145        ('facebook.data.setObjectProperty',
# Line 879 | Line 1150 | function toggleDisplay(id, type) {
1150  
1151    /**
1152     * Read hash value by key.
1153 <   *
1153 >   *
1154     * @param  obj_type      object type's name
1155     * @param  key           hash key
1156     * @param  prop_name     (optional) individual property's name
# Line 892 | Line 1163 | function toggleDisplay(id, type) {
1163     *    API_EC_DATA_QUOTA_EXCEEDED
1164     *    API_EC_DATA_UNKNOWN_ERROR
1165     */
1166 <  public function data_getHashValue($obj_type, $key, $prop_name = null) {
1166 >  public function &data_getHashValue($obj_type, $key, $prop_name = null) {
1167      return $this->call_method
1168        ('facebook.data.getHashValue',
1169         array('obj_type' => $obj_type,
# Line 902 | Line 1173 | function toggleDisplay(id, type) {
1173  
1174    /**
1175     * Write hash value by key.
1176 <   *
1176 >   *
1177     * @param  obj_type      object type's name
1178     * @param  key           hash key
1179     * @param  value         hash value
# Line 915 | Line 1186 | function toggleDisplay(id, type) {
1186     *    API_EC_DATA_QUOTA_EXCEEDED
1187     *    API_EC_DATA_UNKNOWN_ERROR
1188     */
1189 <  public function data_setHashValue($obj_type, $key, $value, $prop_name = null) {
1189 >  public function &data_setHashValue($obj_type, $key, $value, $prop_name = null) {
1190      return $this->call_method
1191        ('facebook.data.setHashValue',
1192         array('obj_type' => $obj_type,
# Line 926 | Line 1197 | function toggleDisplay(id, type) {
1197  
1198    /**
1199     * Increase a hash value by specified increment atomically.
1200 <   *
1200 >   *
1201     * @param  obj_type      object type's name
1202     * @param  key           hash key
1203     * @param  prop_name     individual property's name
# Line 940 | Line 1211 | function toggleDisplay(id, type) {
1211     *    API_EC_DATA_QUOTA_EXCEEDED
1212     *    API_EC_DATA_UNKNOWN_ERROR
1213     */
1214 <  public function data_incHashValue($obj_type, $key, $prop_name, $increment = 1) {
1214 >  public function &data_incHashValue($obj_type, $key, $prop_name, $increment = 1) {
1215      return $this->call_method
1216        ('facebook.data.incHashValue',
1217         array('obj_type' => $obj_type,
# Line 962 | Line 1233 | function toggleDisplay(id, type) {
1233     *    API_EC_DATA_QUOTA_EXCEEDED
1234     *    API_EC_DATA_UNKNOWN_ERROR
1235     */
1236 <  public function data_removeHashKey($obj_type, $key) {
1236 >  public function &data_removeHashKey($obj_type, $key) {
1237      return $this->call_method
1238        ('facebook.data.removeHashKey',
1239         array('obj_type' => $obj_type,
# Line 982 | Line 1253 | function toggleDisplay(id, type) {
1253     *    API_EC_DATA_QUOTA_EXCEEDED
1254     *    API_EC_DATA_UNKNOWN_ERROR
1255     */
1256 <  public function data_removeHashKeys($obj_type, $keys) {
1256 >  public function &data_removeHashKeys($obj_type, $keys) {
1257      return $this->call_method
1258        ('facebook.data.removeHashKeys',
1259         array('obj_type' => $obj_type,
# Line 1007 | Line 1278 | function toggleDisplay(id, type) {
1278     *    API_EC_DATA_QUOTA_EXCEEDED
1279     *    API_EC_DATA_UNKNOWN_ERROR
1280     */
1281 <  public function data_defineAssociation($name, $assoc_type, $assoc_info1,
1281 >  public function &data_defineAssociation($name, $assoc_type, $assoc_info1,
1282                                           $assoc_info2, $inverse = null) {
1283      return $this->call_method
1284        ('facebook.data.defineAssociation',
# Line 1017 | Line 1288 | function toggleDisplay(id, type) {
1288               'assoc_info2' => json_encode($assoc_info2),
1289               'inverse' => $inverse));
1290    }
1291 <  
1291 >
1292    /**
1293     * Undefine an object association.
1294     *
# Line 1031 | Line 1302 | function toggleDisplay(id, type) {
1302     *    API_EC_DATA_QUOTA_EXCEEDED
1303     *    API_EC_DATA_UNKNOWN_ERROR
1304     */
1305 <  public function data_undefineAssociation($name) {
1305 >  public function &data_undefineAssociation($name) {
1306      return $this->call_method
1307        ('facebook.data.undefineAssociation',
1308         array('name' => $name));
# Line 1054 | Line 1325 | function toggleDisplay(id, type) {
1325     *    API_EC_DATA_QUOTA_EXCEEDED
1326     *    API_EC_DATA_UNKNOWN_ERROR
1327     */
1328 <  public function data_renameAssociation($name, $new_name, $new_alias1 = null,
1328 >  public function &data_renameAssociation($name, $new_name, $new_alias1 = null,
1329                                           $new_alias2 = null) {
1330      return $this->call_method
1331        ('facebook.data.renameAssociation',
# Line 1063 | Line 1334 | function toggleDisplay(id, type) {
1334               'new_alias1' => $new_alias1,
1335               'new_alias2' => $new_alias2));
1336    }
1337 <  
1337 >
1338    /**
1339     * Get definition of an object association.
1340     *
# Line 1077 | Line 1348 | function toggleDisplay(id, type) {
1348     *    API_EC_DATA_QUOTA_EXCEEDED
1349     *    API_EC_DATA_UNKNOWN_ERROR
1350     */
1351 <  public function data_getAssociationDefinition($name) {
1351 >  public function &data_getAssociationDefinition($name) {
1352      return $this->call_method
1353        ('facebook.data.getAssociationDefinition',
1354         array('name' => $name));
1355    }
1356 <  
1356 >
1357    /**
1358     * Get definition of all associations.
1359     *
# Line 1093 | Line 1364 | function toggleDisplay(id, type) {
1364     *    API_EC_DATA_QUOTA_EXCEEDED
1365     *    API_EC_DATA_UNKNOWN_ERROR
1366     */
1367 <  public function data_getAssociationDefinitions() {
1367 >  public function &data_getAssociationDefinitions() {
1368      return $this->call_method
1369        ('facebook.data.getAssociationDefinitions',
1370         array());
# Line 1101 | Line 1372 | function toggleDisplay(id, type) {
1372  
1373    /**
1374     * Create or modify an association between two objects.
1375 <   *
1375 >   *
1376     * @param  name        name of association
1377     * @param  obj_id1     id of first object
1378     * @param  obj_id2     id of second object
# Line 1115 | Line 1386 | function toggleDisplay(id, type) {
1386     *    API_EC_DATA_QUOTA_EXCEEDED
1387     *    API_EC_DATA_UNKNOWN_ERROR
1388     */
1389 <  public function data_setAssociation($name, $obj_id1, $obj_id2, $data = null,
1389 >  public function &data_setAssociation($name, $obj_id1, $obj_id2, $data = null,
1390                                        $assoc_time = null) {
1391      return $this->call_method
1392        ('facebook.data.setAssociation',
# Line 1128 | Line 1399 | function toggleDisplay(id, type) {
1399  
1400    /**
1401     * Create or modify associations between objects.
1402 <   *
1402 >   *
1403     * @param  assocs      associations to set
1404     * @param  name        (optional) name of association
1405     * @error
# Line 1139 | Line 1410 | function toggleDisplay(id, type) {
1410     *    API_EC_DATA_QUOTA_EXCEEDED
1411     *    API_EC_DATA_UNKNOWN_ERROR
1412     */
1413 <  public function data_setAssociations($assocs, $name = null) {
1413 >  public function &data_setAssociations($assocs, $name = null) {
1414      return $this->call_method
1415        ('facebook.data.setAssociations',
1416         array('assocs' => json_encode($assocs),
# Line 1148 | Line 1419 | function toggleDisplay(id, type) {
1419  
1420    /**
1421     * Remove an association between two objects.
1422 <   *
1422 >   *
1423     * @param  name        name of association
1424     * @param  obj_id1     id of first object
1425     * @param  obj_id2     id of second object
# Line 1160 | Line 1431 | function toggleDisplay(id, type) {
1431     *    API_EC_DATA_QUOTA_EXCEEDED
1432     *    API_EC_DATA_UNKNOWN_ERROR
1433     */
1434 <  public function data_removeAssociation($name, $obj_id1, $obj_id2) {
1434 >  public function &data_removeAssociation($name, $obj_id1, $obj_id2) {
1435      return $this->call_method
1436        ('facebook.data.removeAssociation',
1437 <       array('obj_id1' => $obj_id1,
1437 >       array('name' => $name,
1438 >             'obj_id1' => $obj_id1,
1439               'obj_id2' => $obj_id2));
1440    }
1441  
1442    /**
1443     * Remove associations between objects by specifying pairs of object ids.
1444 <   *
1444 >   *
1445     * @param  assocs      associations to remove
1446     * @param  name        (optional) name of association
1447     * @error
# Line 1180 | Line 1452 | function toggleDisplay(id, type) {
1452     *    API_EC_DATA_QUOTA_EXCEEDED
1453     *    API_EC_DATA_UNKNOWN_ERROR
1454     */
1455 <  public function data_removeAssociations($assocs, $name = null) {
1455 >  public function &data_removeAssociations($assocs, $name = null) {
1456      return $this->call_method
1457        ('facebook.data.removeAssociations',
1458         array('assocs' => json_encode($assocs),
# Line 1189 | Line 1461 | function toggleDisplay(id, type) {
1461  
1462    /**
1463     * Remove associations between objects by specifying one object id.
1464 <   *
1464 >   *
1465     * @param  name        name of association
1466     * @param  obj_id      who's association to remove
1467     * @error
# Line 1201 | Line 1473 | function toggleDisplay(id, type) {
1473     *    API_EC_DATA_QUOTA_EXCEEDED
1474     *    API_EC_DATA_UNKNOWN_ERROR
1475     */
1476 <  public function data_removeAssociatedObjects($name, $obj_id) {
1476 >  public function &data_removeAssociatedObjects($name, $obj_id) {
1477      return $this->call_method
1478        ('facebook.data.removeAssociatedObjects',
1479         array('name' => $name,
# Line 1224 | Line 1496 | function toggleDisplay(id, type) {
1496     *    API_EC_DATA_QUOTA_EXCEEDED
1497     *    API_EC_DATA_UNKNOWN_ERROR
1498     */
1499 <  public function data_getAssociatedObjects($name, $obj_id, $no_data = true) {
1499 >  public function &data_getAssociatedObjects($name, $obj_id, $no_data = true) {
1500      return $this->call_method
1501        ('facebook.data.getAssociatedObjects',
1502 <       array('obj_id' => $obj_id,
1502 >       array('name' => $name,
1503 >             'obj_id' => $obj_id,
1504               'no_data' => $no_data));
1505    }
1506  
# Line 1246 | Line 1519 | function toggleDisplay(id, type) {
1519     *    API_EC_DATA_QUOTA_EXCEEDED
1520     *    API_EC_DATA_UNKNOWN_ERROR
1521     */
1522 <  public function data_getAssociatedObjectCount($name, $obj_id) {
1522 >  public function &data_getAssociatedObjectCount($name, $obj_id) {
1523      return $this->call_method
1524        ('facebook.data.getAssociatedObjectCount',
1525         array('name' => $name,
# Line 1268 | Line 1541 | function toggleDisplay(id, type) {
1541     *    API_EC_DATA_QUOTA_EXCEEDED
1542     *    API_EC_DATA_UNKNOWN_ERROR
1543     */
1544 <  public function data_getAssociatedObjectCounts($name, $obj_ids) {
1544 >  public function &data_getAssociatedObjectCounts($name, $obj_ids) {
1545      return $this->call_method
1546        ('facebook.data.getAssociatedObjectCounts',
1547         array('name' => $name,
# Line 1289 | Line 1562 | function toggleDisplay(id, type) {
1562     *    API_EC_DATA_QUOTA_EXCEEDED
1563     *    API_EC_DATA_UNKNOWN_ERROR
1564     */
1565 <  public function data_getAssociations($obj_id1, $obj_id2, $no_data = true) {
1565 >  public function &data_getAssociations($obj_id1, $obj_id2, $no_data = true) {
1566      return $this->call_method
1567        ('facebook.data.getAssociations',
1568         array('obj_id1' => $obj_id1,
# Line 1297 | Line 1570 | function toggleDisplay(id, type) {
1570               'no_data' => $no_data));
1571    }
1572  
1573 +  /**
1574 +   * Get the properties that you have set for an app.
1575 +   *
1576 +   * @param  properties  list of properties names to fetch
1577 +   * @return             a map from property name to value
1578 +   */
1579 +  public function admin_getAppProperties($properties) {
1580 +    return json_decode($this->call_method
1581 +                       ('facebook.admin.getAppProperties',
1582 +                        array('properties' => json_encode($properties))), true);
1583 +  }
1584 +
1585 +  /**
1586 +   * Set properties for an app.
1587 +   *
1588 +   * @param  properties  a map from property names to  values
1589 +   * @return             true on success
1590 +   */
1591 +  public function admin_setAppProperties($properties) {
1592 +    return $this->call_method
1593 +      ('facebook.admin.setAppProperties',
1594 +       array('properties' => json_encode($properties)));
1595 +  }
1596 +
1597 +  /**
1598 +   * Returns the allocation limit value for a specified integration point name
1599 +   * Integration point names are defined in lib/api/karma/constants.php in the limit_map
1600 +   * @param string $integration_point_name
1601 +   * @return integration point allocation value
1602 +   */
1603 +  public function &admin_getAllocation($integration_point_name) {
1604 +    return $this->call_method('facebook.admin.getAllocation', array('integration_point_name' => $integration_point_name));
1605 +  }
1606 +
1607 +  /**
1608 +   * Returns values for the specified daily metrics for the current
1609 +   * application, in the given date range (inclusive).
1610 +   *
1611 +   * @param start_date  unix time for the start of the date range
1612 +   * @param end_date    unix time for the end of the date range
1613 +   * @param metrics     list of daily metrics to look up
1614 +   * @return            a list of the values for those metrics
1615 +   */
1616 +  public function &admin_getDailyMetrics($start_date, $end_date, $metrics) {
1617 +    return $this->call_method('admin.getDailyMetrics',
1618 +                              array('start_date' => $start_date,
1619 +                                    'end_date' => $end_date,
1620 +                                    'metrics' => json_encode($metrics)));
1621 +  }
1622 +
1623 +  /**
1624 +   * Returns values for the specified metrics for the current
1625 +   * application, in the given time range.  The metrics are collected
1626 +   * for fixed-length periods, and the times represent midnight at
1627 +   * the end of each period.
1628 +   *
1629 +   * @param start_time  unix time for the start of the range
1630 +   * @param end_time    unix time for the end of the range
1631 +   * @param period      number of seconds in the desired period
1632 +   * @param metrics     list of metrics to look up
1633 +   * @return            a list of the values for those metrics
1634 +   */
1635 +  public function &admin_getMetrics($start_time, $end_time, $period, $metrics) {
1636 +    return $this->call_method('admin.getMetrics',
1637 +                              array('start_time' => $start_time,
1638 +                                    'end_time' => $end_time,
1639 +                                    'period' => $period,
1640 +                                    'metrics' => json_encode($metrics)));
1641 +  }
1642 +
1643 +
1644 +
1645    /* UTILITY FUNCTIONS */
1646  
1647 <  public function call_method($method, $params) {
1648 <    if ($this->json) {
1649 <      $json = $this->post_request($method, $params);
1650 <      # XXX: silly facebook with its invalid JSON
1651 <      $valid = preg_match('/^[\[{].*[\]}]$/', $json);
1652 <      $array = json_decode($valid ? $json : "[$json]", true);
1653 <      $result = $valid ? $array : $array[0];
1654 <    } else {
1655 <      $xml = $this->post_request($method, $params);
1656 <      $sxml = simplexml_load_string($xml);
1657 <      $result = self::convert_simplexml_to_array($sxml);
1658 <      if ($GLOBALS['facebook_config']['debug']) {
1659 <        // output the raw xml and its corresponding php object, for debugging:
1660 <        print '<div style="margin: 10px 30px; padding: 5px; border: 2px solid black; background: gray; color: white; font-size: 12px; font-weight: bold;">';
1661 <        $this->cur_id++;
1662 <        print $this->cur_id . ': Called ' . $method . ', show ' .
1663 <              '<a href=# onclick="return toggleDisplay(' . $this->cur_id . ', \'params\');">Params</a> | '.
1664 <              '<a href=# onclick="return toggleDisplay(' . $this->cur_id . ', \'xml\');">XML</a> | '.
1665 <              '<a href=# onclick="return toggleDisplay(' . $this->cur_id . ', \'sxml\');">SXML</a> | '.
1666 <              '<a href=# onclick="return toggleDisplay(' . $this->cur_id . ', \'php\');">PHP</a>';
1322 <        print '<pre id="params'.$this->cur_id.'" style="display: none; overflow: auto;">'.print_r($params, true).'</pre>';
1323 <        print '<pre id="xml'.$this->cur_id.'" style="display: none; overflow: auto;">'.htmlspecialchars($xml).'</pre>';
1324 <        print '<pre id="php'.$this->cur_id.'" style="display: none; overflow: auto;">'.print_r($result, true).'</pre>';
1325 <        print '<pre id="sxml'.$this->cur_id.'" style="display: none; overflow: auto;">'.print_r($sxml, true).'</pre>';
1326 <        print '</div>';
1647 >  public function & call_method($method, $params) {
1648 >
1649 >    //Check if we are in batch mode
1650 >    if($this->batch_queue === null) {
1651 >      if ($this->call_as_apikey) {
1652 >        $params['call_as_apikey'] = $this->call_as_apikey;
1653 >      }
1654 >      if ($this->json)
1655 >      {
1656 >        $json = $this->post_request($method, $params);
1657 >        # XXX: silly facebook with its invalid JSON
1658 >        $valid = preg_match('/^[\[{].*[\]}]$/', $json);
1659 >        $array = json_decode($valid ? $json : "[$json]", true);
1660 >        $result = $valid ? $array : $array[0];
1661 >      } else {
1662 >        $xml = $this->post_request($method, $params);
1663 >        $result = $this->convert_xml_to_result($xml, $method, $params);
1664 >      }
1665 >      if (is_array($result) && isset($result['error_code'])) {
1666 >        throw new FacebookRestClientException($result['error_msg'], $result['error_code']);
1667        }
1668      }
1669 <    if (is_array($result) && isset($result['error_code'])) {
1670 <      throw new FacebookRestClientException($result['error_msg'], $result['error_code']);
1669 >    else {
1670 >      $result = null;
1671 >      $batch_item = array('m' => $method, 'p' => $params, 'r' => & $result);
1672 >      $this->batch_queue[] = $batch_item;
1673      }
1674 +
1675      return $result;
1676    }
1677  
1678 <  public function post_request($method, $params) {
1678 >  private function convert_xml_to_result($xml, $method, $params) {
1679 >    $sxml = simplexml_load_string($xml);
1680 >    $result = self::convert_simplexml_to_array($sxml);
1681 >
1682 >
1683 >    if (!empty($GLOBALS['facebook_config']['debug'])) {
1684 >      // output the raw xml and its corresponding php object, for debugging:
1685 >      print '<div style="margin: 10px 30px; padding: 5px; border: 2px solid black; background: gray; color: white; font-size: 12px; font-weight: bold;">';
1686 >      $this->cur_id++;
1687 >      print $this->cur_id . ': Called ' . $method . ', show ' .
1688 >            '<a href=# onclick="return toggleDisplay(' . $this->cur_id . ', \'params\');">Params</a> | '.
1689 >            '<a href=# onclick="return toggleDisplay(' . $this->cur_id . ', \'xml\');">XML</a> | '.
1690 >            '<a href=# onclick="return toggleDisplay(' . $this->cur_id . ', \'sxml\');">SXML</a> | '.
1691 >            '<a href=# onclick="return toggleDisplay(' . $this->cur_id . ', \'php\');">PHP</a>';
1692 >      print '<pre id="params'.$this->cur_id.'" style="display: none; overflow: auto;">'.print_r($params, true).'</pre>';
1693 >      print '<pre id="xml'.$this->cur_id.'" style="display: none; overflow: auto;">'.htmlspecialchars($xml).'</pre>';
1694 >      print '<pre id="php'.$this->cur_id.'" style="display: none; overflow: auto;">'.print_r($result, true).'</pre>';
1695 >      print '<pre id="sxml'.$this->cur_id.'" style="display: none; overflow: auto;">'.print_r($sxml, true).'</pre>';
1696 >      print '</div>';
1697 >    }
1698 >    return $result;
1699 >  }
1700 >
1701 >
1702 >
1703 >  private function create_post_string($method, $params) {
1704      $params['method'] = $method;
1705      $params['session_key'] = $this->session_key;
1706      $params['api_key'] = $this->api_key;
# Line 1352 | Line 1720 | function toggleDisplay(id, type) {
1720        $post_params[] = $key.'='.urlencode($val);
1721      }
1722      $post_params[] = 'sig='.Facebook::generate_sig($params, $this->secret);
1723 <    $post_string = implode('&', $post_params);
1723 >    return implode('&', $post_params);
1724 >  }
1725  
1726 <    if ($this->json) {
1727 <      $result = file_get_contents($this->server_addr, false, stream_context_create(
1728 <        array('http' =>
1729 <              array('method' => 'POST',
1730 <                    'header' => 'Content-type: application/x-www-form-urlencoded'."\r\n".
1362 <                                'User-Agent: Facebook API PHP5 Client 1.1 (non-curl) '.phpversion()."\r\n".
1363 <                                'Content-length: ' . strlen($post_string),
1364 <                    'content' => $post_string))));
1365 <    } elseif (function_exists('curl_init')) {
1726 >  public function post_request($method, $params) {
1727 >
1728 >    $post_string = $this->create_post_string($method, $params);
1729 >
1730 >    if (function_exists('curl_init')) {
1731        // Use CURL if installed...
1732        $ch = curl_init();
1733        curl_setopt($ch, CURLOPT_URL, $this->server_addr);
# Line 1408 | Line 1773 | function toggleDisplay(id, type) {
1773        return $arr;
1774      } else {
1775        return (string)$sxml;
1776 <    }
1776 >    }
1777    }
1778 +
1779   }
1780  
1781 +
1782   class FacebookRestClientException extends Exception {
1783   }
1784  
# Line 1469 | Line 1836 | class FacebookAPIErrorCodes {
1836    const API_EC_DATA_OBJECT_NOT_FOUND = 803;
1837    const API_EC_DATA_OBJECT_ALREADY_EXISTS = 804;
1838    const API_EC_DATA_DATABASE_ERROR = 805;
1839 <
1839 >
1840 >
1841 >  /*
1842 >   * Batch ERROR
1843 >   */
1844 >  const API_EC_BATCH_ALREADY_STARTED = 900;
1845 >  const API_EC_BATCH_NOT_STARTED = 901;
1846 >  const API_EC_BATCH_METHOD_NOT_ALLOWED_IN_BATCH_MODE = 902;
1847 >
1848    public static $api_error_descriptions = array(
1849        API_EC_SUCCESS           => 'Success',
1850        API_EC_UNKNOWN           => 'An unknown error occurred',
# Line 1502 | Line 1877 | class FacebookAPIErrorCodes {
1877        API_EC_DATA_OBJECT_NOT_FOUND => 'Specified object cannot be found',
1878        API_EC_DATA_OBJECT_ALREADY_EXISTS => 'Specified object already exists',
1879        API_EC_DATA_DATABASE_ERROR => 'A database error occurred. Please try again',
1880 +      API_EC_BATCH_ALREADY_STARTED => 'begin_batch already called, please make sure to call end_batch first',
1881 +      API_EC_BATCH_NOT_STARTED => 'end_batch called before start_batch',
1882 +      API_EC_BATCH_METHOD_NOT_ALLOWED_IN_BATCH_MODE => 'this method is not allowed in batch mode',
1883    );
1884   }
1507
1508 $profile_field_array = array(
1509    "about_me",
1510    "activities",
1511    "affiliations",
1512    "birthday",
1513    "books",
1514    "current_location",
1515    "education_history",
1516    "first_name",
1517    "hometown_location",
1518    "hs_info",
1519    "interests",
1520    "is_app_user",
1521    "last_name",
1522    "meeting_for",
1523    "meeting_sex",
1524    "movies",
1525    "music",
1526    "name",
1527    "notes_count",
1528    "pic",
1529    "pic_big",
1530    "pic_small",
1531    "political",
1532    "profile_update_time",
1533    "quotes",
1534    "relationship_status",
1535    "religion",
1536    "sex",
1537    "significant_other_id",
1538    "status",
1539    "timezone",
1540    "tv",
1541    "wall_count",
1542    "work_history");
1543 ?>

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines