forked from GNUsocial/gnu-social
		
	Merge branch 'master' of gitorious.org:statusnet/mainline
This commit is contained in:
		@@ -97,6 +97,10 @@ class Notice extends Memcached_DataObject
 | 
				
			|||||||
        // For auditing purposes, save a record that the notice
 | 
					        // For auditing purposes, save a record that the notice
 | 
				
			||||||
        // was deleted.
 | 
					        // was deleted.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // @fixme we have some cases where things get re-run and so the
 | 
				
			||||||
 | 
					        // insert fails.
 | 
				
			||||||
 | 
					        $deleted = Deleted_notice::staticGet('id', $this->id);
 | 
				
			||||||
 | 
					        if (!$deleted) {
 | 
				
			||||||
            $deleted = new Deleted_notice();
 | 
					            $deleted = new Deleted_notice();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $deleted->id         = $this->id;
 | 
					            $deleted->id         = $this->id;
 | 
				
			||||||
@@ -106,6 +110,7 @@ class Notice extends Memcached_DataObject
 | 
				
			|||||||
            $deleted->deleted    = common_sql_now();
 | 
					            $deleted->deleted    = common_sql_now();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $deleted->insert();
 | 
					            $deleted->insert();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Clear related records
 | 
					        // Clear related records
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -45,7 +45,9 @@ class Facebook {
 | 
				
			|||||||
  public $user;
 | 
					  public $user;
 | 
				
			||||||
  public $profile_user;
 | 
					  public $profile_user;
 | 
				
			||||||
  public $canvas_user;
 | 
					  public $canvas_user;
 | 
				
			||||||
 | 
					  public $ext_perms = array();
 | 
				
			||||||
  protected $base_domain;
 | 
					  protected $base_domain;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*
 | 
					  /*
 | 
				
			||||||
   * Create a Facebook client like this:
 | 
					   * Create a Facebook client like this:
 | 
				
			||||||
   *
 | 
					   *
 | 
				
			||||||
@@ -104,17 +106,17 @@ class Facebook {
 | 
				
			|||||||
   *
 | 
					   *
 | 
				
			||||||
   * For nitty-gritty details of when each of these is used, check out
 | 
					   * For nitty-gritty details of when each of these is used, check out
 | 
				
			||||||
   * http://wiki.developers.facebook.com/index.php/Verifying_The_Signature
 | 
					   * http://wiki.developers.facebook.com/index.php/Verifying_The_Signature
 | 
				
			||||||
   *
 | 
					 | 
				
			||||||
   * @param bool  resolve_auth_token  convert an auth token into a session
 | 
					 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  public function validate_fb_params($resolve_auth_token=true) {
 | 
					  public function validate_fb_params() {
 | 
				
			||||||
    $this->fb_params = $this->get_valid_fb_params($_POST, 48 * 3600, 'fb_sig');
 | 
					    $this->fb_params = $this->get_valid_fb_params($_POST, 48 * 3600, 'fb_sig');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // note that with preload FQL, it's possible to receive POST params in
 | 
					    // note that with preload FQL, it's possible to receive POST params in
 | 
				
			||||||
    // addition to GET, so use a different prefix to differentiate them
 | 
					    // addition to GET, so use a different prefix to differentiate them
 | 
				
			||||||
    if (!$this->fb_params) {
 | 
					    if (!$this->fb_params) {
 | 
				
			||||||
      $fb_params = $this->get_valid_fb_params($_GET, 48 * 3600, 'fb_sig');
 | 
					      $fb_params = $this->get_valid_fb_params($_GET, 48 * 3600, 'fb_sig');
 | 
				
			||||||
      $fb_post_params = $this->get_valid_fb_params($_POST, 48 * 3600, 'fb_post_sig');
 | 
					      $fb_post_params = $this->get_valid_fb_params($_POST,
 | 
				
			||||||
 | 
					                                                   48 * 3600, // 48 hours
 | 
				
			||||||
 | 
					                                                   'fb_post_sig');
 | 
				
			||||||
      $this->fb_params = array_merge($fb_params, $fb_post_params);
 | 
					      $this->fb_params = array_merge($fb_params, $fb_post_params);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -128,6 +130,9 @@ class Facebook {
 | 
				
			|||||||
                            $this->fb_params['canvas_user'] : null;
 | 
					                            $this->fb_params['canvas_user'] : null;
 | 
				
			||||||
      $this->base_domain  = isset($this->fb_params['base_domain']) ?
 | 
					      $this->base_domain  = isset($this->fb_params['base_domain']) ?
 | 
				
			||||||
                            $this->fb_params['base_domain'] : null;
 | 
					                            $this->fb_params['base_domain'] : null;
 | 
				
			||||||
 | 
					      $this->ext_perms    = isset($this->fb_params['ext_perms']) ?
 | 
				
			||||||
 | 
					                            explode(',', $this->fb_params['ext_perms'])
 | 
				
			||||||
 | 
					                            : array();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (isset($this->fb_params['session_key'])) {
 | 
					      if (isset($this->fb_params['session_key'])) {
 | 
				
			||||||
        $session_key =  $this->fb_params['session_key'];
 | 
					        $session_key =  $this->fb_params['session_key'];
 | 
				
			||||||
@@ -141,13 +146,11 @@ class Facebook {
 | 
				
			|||||||
      $this->set_user($user,
 | 
					      $this->set_user($user,
 | 
				
			||||||
                      $session_key,
 | 
					                      $session_key,
 | 
				
			||||||
                      $expires);
 | 
					                      $expires);
 | 
				
			||||||
    }
 | 
					    } else if ($cookies =
 | 
				
			||||||
 | 
					               $this->get_valid_fb_params($_COOKIE, null, $this->api_key)) {
 | 
				
			||||||
      // if no Facebook parameters were found in the GET or POST variables,
 | 
					      // if no Facebook parameters were found in the GET or POST variables,
 | 
				
			||||||
      // then fall back to cookies, which may have cached user information
 | 
					      // then fall back to cookies, which may have cached user information
 | 
				
			||||||
      // Cookies are also used to receive session data via the Javascript API
 | 
					      // Cookies are also used to receive session data via the Javascript API
 | 
				
			||||||
    else if ($cookies =
 | 
					 | 
				
			||||||
             $this->get_valid_fb_params($_COOKIE, null, $this->api_key)) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      $base_domain_cookie = 'base_domain_' . $this->api_key;
 | 
					      $base_domain_cookie = 'base_domain_' . $this->api_key;
 | 
				
			||||||
      if (isset($_COOKIE[$base_domain_cookie])) {
 | 
					      if (isset($_COOKIE[$base_domain_cookie])) {
 | 
				
			||||||
        $this->base_domain = $_COOKIE[$base_domain_cookie];
 | 
					        $this->base_domain = $_COOKIE[$base_domain_cookie];
 | 
				
			||||||
@@ -160,25 +163,6 @@ class Facebook {
 | 
				
			|||||||
                      $cookies['session_key'],
 | 
					                      $cookies['session_key'],
 | 
				
			||||||
                      $expires);
 | 
					                      $expires);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // finally, if we received no parameters, but the 'auth_token' GET var
 | 
					 | 
				
			||||||
    // is present, then we are in the middle of auth handshake,
 | 
					 | 
				
			||||||
    // so go ahead and create the session
 | 
					 | 
				
			||||||
    else if ($resolve_auth_token && isset($_GET['auth_token']) &&
 | 
					 | 
				
			||||||
             $session = $this->do_get_session($_GET['auth_token'])) {
 | 
					 | 
				
			||||||
      if ($this->generate_session_secret &&
 | 
					 | 
				
			||||||
          !empty($session['secret'])) {
 | 
					 | 
				
			||||||
        $session_secret = $session['secret'];
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (isset($session['base_domain'])) {
 | 
					 | 
				
			||||||
        $this->base_domain = $session['base_domain'];
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      $this->set_user($session['uid'],
 | 
					 | 
				
			||||||
                      $session['session_key'],
 | 
					 | 
				
			||||||
                      $session['expires'],
 | 
					 | 
				
			||||||
                      isset($session_secret) ? $session_secret : null);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return !empty($this->fb_params);
 | 
					    return !empty($this->fb_params);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -309,11 +293,28 @@ class Facebook {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  // require_add and require_install have been removed.
 | 
					  // require_add and require_install have been removed.
 | 
				
			||||||
  // see http://developer.facebook.com/news.php?blog=1&story=116 for more details
 | 
					  // see http://developer.facebook.com/news.php?blog=1&story=116 for more details
 | 
				
			||||||
  public function require_login() {
 | 
					  public function require_login($required_permissions = '') {
 | 
				
			||||||
    if ($user = $this->get_loggedin_user()) {
 | 
					    $user = $this->get_loggedin_user();
 | 
				
			||||||
 | 
					    $has_permissions = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ($required_permissions) {
 | 
				
			||||||
 | 
					      $this->require_frame();
 | 
				
			||||||
 | 
					      $permissions = array_map('trim', explode(',', $required_permissions));
 | 
				
			||||||
 | 
					      foreach ($permissions as $permission) {
 | 
				
			||||||
 | 
					        if (!in_array($permission, $this->ext_perms)) {
 | 
				
			||||||
 | 
					          $has_permissions = false;
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ($user && $has_permissions) {
 | 
				
			||||||
      return $user;
 | 
					      return $user;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    $this->redirect($this->get_login_url(self::current_url(), $this->in_frame()));
 | 
					
 | 
				
			||||||
 | 
					    $this->redirect(
 | 
				
			||||||
 | 
					      $this->get_login_url(self::current_url(), $this->in_frame(),
 | 
				
			||||||
 | 
					                           $required_permissions));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public function require_frame() {
 | 
					  public function require_frame() {
 | 
				
			||||||
@@ -342,10 +343,11 @@ class Facebook {
 | 
				
			|||||||
    return $page . '?' . http_build_query($params);
 | 
					    return $page . '?' . http_build_query($params);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public function get_login_url($next, $canvas) {
 | 
					  public function get_login_url($next, $canvas, $req_perms = '') {
 | 
				
			||||||
    $page = self::get_facebook_url().'/login.php';
 | 
					    $page = self::get_facebook_url().'/login.php';
 | 
				
			||||||
    $params = array('api_key'   => $this->api_key,
 | 
					    $params = array('api_key'   => $this->api_key,
 | 
				
			||||||
                    'v'       => '1.0');
 | 
					                    'v'         => '1.0',
 | 
				
			||||||
 | 
					                    'req_perms' => $req_perms);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ($next) {
 | 
					    if ($next) {
 | 
				
			||||||
      $params['next'] = $next;
 | 
					      $params['next'] = $next;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -569,7 +569,7 @@ function toggleDisplay(id, type) {
 | 
				
			|||||||
    return $this->call_method('facebook.events.invite',
 | 
					    return $this->call_method('facebook.events.invite',
 | 
				
			||||||
                              array('eid' => $eid,
 | 
					                              array('eid' => $eid,
 | 
				
			||||||
                                    'uids' => $uids,
 | 
					                                    'uids' => $uids,
 | 
				
			||||||
                                    'personal_message', $personal_message));
 | 
					                                    'personal_message' => $personal_message));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
@@ -1350,53 +1350,6 @@ function toggleDisplay(id, type) {
 | 
				
			|||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					 | 
				
			||||||
   * Dashboard API
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /**
 | 
					 | 
				
			||||||
   * Set the news for the specified user.
 | 
					 | 
				
			||||||
   *
 | 
					 | 
				
			||||||
   * @param int    $uid     The user for whom you are setting news for
 | 
					 | 
				
			||||||
   * @param string $news    Text of news to display
 | 
					 | 
				
			||||||
   *
 | 
					 | 
				
			||||||
   * @return bool   Success
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
  public function dashboard_setNews($uid, $news) {
 | 
					 | 
				
			||||||
    return $this->call_method('facebook.dashboard.setNews',
 | 
					 | 
				
			||||||
                              array('uid'  => $uid,
 | 
					 | 
				
			||||||
                                    'news' => $news)
 | 
					 | 
				
			||||||
                             );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /**
 | 
					 | 
				
			||||||
   * Get the current news of the specified user.
 | 
					 | 
				
			||||||
   *
 | 
					 | 
				
			||||||
   * @param int    $uid     The user to get the news of
 | 
					 | 
				
			||||||
   *
 | 
					 | 
				
			||||||
   * @return string   The text of the current news for the user
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
  public function dashboard_getNews($uid) {
 | 
					 | 
				
			||||||
    return json_decode(
 | 
					 | 
				
			||||||
      $this->call_method('facebook.dashboard.getNews',
 | 
					 | 
				
			||||||
                         array('uid' => $uid)
 | 
					 | 
				
			||||||
                        ), true);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /**
 | 
					 | 
				
			||||||
   * Set the news for the specified user.
 | 
					 | 
				
			||||||
   *
 | 
					 | 
				
			||||||
   * @param int    $uid     The user you are clearing the news of
 | 
					 | 
				
			||||||
   *
 | 
					 | 
				
			||||||
   * @return bool   Success
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
  public function dashboard_clearNews($uid) {
 | 
					 | 
				
			||||||
    return $this->call_method('facebook.dashboard.clearNews',
 | 
					 | 
				
			||||||
                              array('uid' => $uid)
 | 
					 | 
				
			||||||
                             );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Creates a note with the specified title and content.
 | 
					   * Creates a note with the specified title and content.
 | 
				
			||||||
@@ -2005,7 +1958,7 @@ function toggleDisplay(id, type) {
 | 
				
			|||||||
   * @return  array  A list of strings describing any compile errors for the
 | 
					   * @return  array  A list of strings describing any compile errors for the
 | 
				
			||||||
   *                 submitted FBML
 | 
					   *                 submitted FBML
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  function profile_setFBML($markup,
 | 
					  public function profile_setFBML($markup,
 | 
				
			||||||
                           $uid=null,
 | 
					                           $uid=null,
 | 
				
			||||||
                           $profile='',
 | 
					                           $profile='',
 | 
				
			||||||
                           $profile_action='',
 | 
					                           $profile_action='',
 | 
				
			||||||
@@ -3267,9 +3220,8 @@ function toggleDisplay(id, type) {
 | 
				
			|||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      $get['v'] = '1.0';
 | 
					      $get['v'] = '1.0';
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (isset($this->use_ssl_resources) &&
 | 
					    if (isset($this->use_ssl_resources)) {
 | 
				
			||||||
        $this->use_ssl_resources) {
 | 
					      $post['return_ssl_resources'] = (bool) $this->use_ssl_resources;
 | 
				
			||||||
      $post['return_ssl_resources'] = true;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return array($get, $post);
 | 
					    return array($get, $post);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -81,114 +81,286 @@ function isFacebookBound($notice, $flink) {
 | 
				
			|||||||
function facebookBroadcastNotice($notice)
 | 
					function facebookBroadcastNotice($notice)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    $facebook = getFacebook();
 | 
					    $facebook = getFacebook();
 | 
				
			||||||
    $flink = Foreign_link::getByUserID($notice->profile_id, FACEBOOK_SERVICE);
 | 
					    $flink = Foreign_link::getByUserID(
 | 
				
			||||||
 | 
					        $notice->profile_id,
 | 
				
			||||||
 | 
					        FACEBOOK_SERVICE
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (isFacebookBound($notice, $flink)) {
 | 
					    if (isFacebookBound($notice, $flink)) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Okay, we're good to go, update the FB status
 | 
					        // Okay, we're good to go, update the FB status
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $status = null;
 | 
					 | 
				
			||||||
        $fbuid = $flink->foreign_id;
 | 
					        $fbuid = $flink->foreign_id;
 | 
				
			||||||
        $user = $flink->getUser();
 | 
					        $user = $flink->getUser();
 | 
				
			||||||
        $attachments  = $notice->attachments();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Get the status 'verb' (prefix) the user has set
 | 
					            // Check permissions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // XXX: Does this call count against our per user FB request limit?
 | 
					            common_debug(
 | 
				
			||||||
            // If so we should consider storing verb elsewhere or not storing
 | 
					                'FacebookPlugin - checking for publish_stream permission for user '
 | 
				
			||||||
 | 
					                . "$user->nickname ($user->id), Facebook UID: $fbuid"
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $prefix = trim($facebook->api_client->data_getUserPreference(FACEBOOK_NOTICE_PREFIX,
 | 
					            // NOTE: $facebook->api_client->users_hasAppPermission('publish_stream', $fbuid)
 | 
				
			||||||
                                                                         $fbuid));
 | 
					            // has been returning bogus results, so we're using FQL to check for
 | 
				
			||||||
 | 
					            // publish_stream permission now
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $status = "$prefix $notice->content";
 | 
					            $fql = "SELECT publish_stream FROM permissions WHERE uid = $fbuid";
 | 
				
			||||||
 | 
					            $result = $facebook->api_client->fql_query($fql);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            common_debug("FacebookPlugin - checking for publish_stream permission for user $user->id");
 | 
					            $canPublish = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $can_publish = $facebook->api_client->users_hasAppPermission('publish_stream',
 | 
					            if (!empty($result)) {
 | 
				
			||||||
                                                                         $fbuid);
 | 
					                $canPublish = $result[0]['publish_stream'];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            common_debug("FacebookPlugin - checking for status_update permission for user $user->id");
 | 
					            if ($canPublish == 1) {
 | 
				
			||||||
 | 
					                common_debug(
 | 
				
			||||||
 | 
					                    "FacebookPlugin - $user->nickname ($user->id), Facebook UID: $fbuid "
 | 
				
			||||||
 | 
					                    . 'has publish_stream permission.'
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                common_debug(
 | 
				
			||||||
 | 
					                    "FacebookPlugin - $user->nickname ($user->id), Facebook UID: $fbuid "
 | 
				
			||||||
 | 
					                    . 'does NOT have publish_stream permission. Facebook '
 | 
				
			||||||
 | 
					                    . 'returned: ' . var_export($result, true)
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $can_update  = $facebook->api_client->users_hasAppPermission('status_update',
 | 
					            common_debug(
 | 
				
			||||||
                                                                         $fbuid);
 | 
					                'FacebookPlugin - checking for status_update permission for user '
 | 
				
			||||||
            if (!empty($attachments) && $can_publish == 1) {
 | 
					                . "$user->nickname ($user->id), Facebook UID: $fbuid. "
 | 
				
			||||||
                $fbattachment = format_attachments($attachments);
 | 
					            );
 | 
				
			||||||
                $facebook->api_client->stream_publish($status, $fbattachment,
 | 
					
 | 
				
			||||||
                                                      null, null, $fbuid);
 | 
					            $canUpdate = $facebook->api_client->users_hasAppPermission(
 | 
				
			||||||
                common_log(LOG_INFO,
 | 
					                'status_update',
 | 
				
			||||||
                           "FacebookPlugin - Posted notice $notice->id w/attachment " .
 | 
					                $fbuid
 | 
				
			||||||
                           "to Facebook user's stream (fbuid = $fbuid).");
 | 
					            );
 | 
				
			||||||
            } elseif ($can_update == 1 || $can_publish == 1) {
 | 
					
 | 
				
			||||||
                $facebook->api_client->users_setStatus($status, $fbuid, false, true);
 | 
					            if ($canUpdate == 1) {
 | 
				
			||||||
                common_log(LOG_INFO,
 | 
					                common_debug(
 | 
				
			||||||
                           "FacebookPlugin - Posted notice $notice->id to Facebook " .
 | 
					                    "FacebookPlugin - $user->nickname ($user->id), Facebook UID: $fbuid "
 | 
				
			||||||
                           "as a status update (fbuid = $fbuid).");
 | 
					                    . 'has status_update permission.'
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                common_debug(
 | 
				
			||||||
 | 
					                    "FacebookPlugin - $user->nickname ($user->id), Facebook UID: $fbuid "
 | 
				
			||||||
 | 
					                    .'does NOT have status_update permission. Facebook '
 | 
				
			||||||
 | 
					                    . 'returned: ' . var_export($canPublish, true)
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Post to Facebook
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($notice->hasAttachments() && $canPublish == 1) {
 | 
				
			||||||
 | 
					                publishStream($notice, $user, $fbuid);
 | 
				
			||||||
 | 
					            } elseif ($canUpdate == 1 || $canPublish == 1) {
 | 
				
			||||||
 | 
					                statusUpdate($notice, $user, $fbuid);
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                $msg = "FacebookPlugin - Not sending notice $notice->id to Facebook " .
 | 
					                $msg = "FacebookPlugin - Not sending notice $notice->id to Facebook " .
 | 
				
			||||||
                  "because user $user->nickname hasn't given the " .
 | 
					                  "because user $user->nickname has not given the " .
 | 
				
			||||||
                  'Facebook app \'status_update\' or \'publish_stream\' permission.';
 | 
					                  'Facebook app \'status_update\' or \'publish_stream\' permission.';
 | 
				
			||||||
                common_log(LOG_WARNING, $msg);
 | 
					                common_log(LOG_WARNING, $msg);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Finally, attempt to update the user's profile box
 | 
					            // Finally, attempt to update the user's profile box
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if ($can_publish == 1 || $can_update == 1) {
 | 
					            if ($canPublish == 1 || $canUpdate == 1) {
 | 
				
			||||||
                updateProfileBox($facebook, $flink, $notice);
 | 
					                updateProfileBox($facebook, $flink, $notice, $user);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        } catch (FacebookRestClientException $e) {
 | 
					        } catch (FacebookRestClientException $e) {
 | 
				
			||||||
 | 
					            return handleFacebookError($e, $notice, $flink);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function handleFacebookError($e, $notice, $flink)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    $fbuid  = $flink->foreign_id;
 | 
				
			||||||
 | 
					    $user   = $flink->getUser();
 | 
				
			||||||
    $code   = $e->getCode();
 | 
					    $code   = $e->getCode();
 | 
				
			||||||
 | 
					    $errmsg = $e->getMessage();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $msg = "FacebookPlugin - Facebook returned error code $code: " .
 | 
					    // XXX: Check for any others?
 | 
				
			||||||
              $e->getMessage() . ' - ' .
 | 
					    switch($code) {
 | 
				
			||||||
              "Unable to update Facebook status (notice $notice->id) " .
 | 
					     case 100: // Invalid parameter
 | 
				
			||||||
              "for $user->nickname (user id: $user->id)!";
 | 
					        $msg = "FacebookPlugin - Facebook claims notice %d was posted with an invalid parameter (error code 100):"
 | 
				
			||||||
 | 
					            . "\"%s\" (Notice details: nickname=%s, user ID=%d, Facebook ID=%d, notice content=\"%s\"). "
 | 
				
			||||||
            common_log(LOG_WARNING, $msg);
 | 
					            . "Removing notice from the Facebook queue for safety.";
 | 
				
			||||||
 | 
					        common_log(
 | 
				
			||||||
            if ($code == 100 || $code == 200 || $code == 250) {
 | 
					            LOG_ERR, sprintf(
 | 
				
			||||||
 | 
					                $msg,
 | 
				
			||||||
                // 100 The account is 'inactive' (probably - this is not well documented)
 | 
					                $notice->id,
 | 
				
			||||||
                // 200 The application does not have permission to operate on the passed in uid parameter.
 | 
					                $errmsg,
 | 
				
			||||||
                // 250 Updating status requires the extended permission status_update or publish_stream.
 | 
					                $user->nickname,
 | 
				
			||||||
                // see: http://wiki.developers.facebook.com/index.php/Users.setStatus#Example_Return_XML
 | 
					                $user->id,
 | 
				
			||||||
 | 
					                $fbuid,
 | 
				
			||||||
 | 
					                $notice->content
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					     case 200: // Permissions error
 | 
				
			||||||
 | 
					     case 250: // Updating status requires the extended permission status_update
 | 
				
			||||||
        remove_facebook_app($flink);
 | 
					        remove_facebook_app($flink);
 | 
				
			||||||
 | 
					        return true; // dequeue
 | 
				
			||||||
            } else if ($code == 341) {
 | 
					        break;
 | 
				
			||||||
                // 341 Feed action request limit reached - Unable to update Facebook status
 | 
					     case 341: // Feed action request limit reached
 | 
				
			||||||
                // Reposting immediately probably won't work, so drop the message for now. :(
 | 
					            $msg = "FacebookPlugin - User %s (User ID=%d, Facebook ID=%d) has exceeded "
 | 
				
			||||||
 | 
					                   . "his/her limit for posting notices to Facebook today. Dequeuing "
 | 
				
			||||||
                common_log(LOG_ERR, "Facebook rate limit hit: dropping notice $notice->id");
 | 
					                   . "notice %d.";
 | 
				
			||||||
 | 
					            common_log(
 | 
				
			||||||
 | 
					                LOG_INFO, sprintf(
 | 
				
			||||||
 | 
					                    $msg,
 | 
				
			||||||
 | 
					                    $user->nickname,
 | 
				
			||||||
 | 
					                    $user->id,
 | 
				
			||||||
 | 
					                    $fbuid,
 | 
				
			||||||
 | 
					                    $notice->id
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
						// @fixme: We want to rety at a later time when the throttling has expired
 | 
				
			||||||
 | 
						// instead of just giving up.
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					     default:
 | 
				
			||||||
 | 
					        $msg = "FacebookPlugin - Facebook returned an error we don't know how to deal with while trying to "
 | 
				
			||||||
 | 
					            . "post notice %d. Error code: %d, error message: \"%s\". (Notice details: "
 | 
				
			||||||
 | 
					            . "nickname=%s, user ID=%d, Facebook ID=%d, notice content=\"%s\"). Removing notice "
 | 
				
			||||||
 | 
						    . "from the Facebook queue for safety.";
 | 
				
			||||||
 | 
					        common_log(
 | 
				
			||||||
 | 
					            LOG_ERR, sprintf(
 | 
				
			||||||
 | 
					                $msg,
 | 
				
			||||||
 | 
					                $notice->id,
 | 
				
			||||||
 | 
					                $code,
 | 
				
			||||||
 | 
					                $errmsg,
 | 
				
			||||||
 | 
					                $user->nickname,
 | 
				
			||||||
 | 
					                $user->id,
 | 
				
			||||||
 | 
					                $fbuid,
 | 
				
			||||||
 | 
					                $notice->content
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        return true; // dequeue
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function statusUpdate($notice, $user, $fbuid)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    common_debug(
 | 
				
			||||||
 | 
					        "FacebookPlugin - Attempting to post notice $notice->id "
 | 
				
			||||||
 | 
					        . "as a status update for $user->nickname ($user->id), "
 | 
				
			||||||
 | 
					        . "Facebook UID: $fbuid"
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $text = formatNotice($notice, $user, $fbuid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $facebook = getFacebook();
 | 
				
			||||||
 | 
					    $result = $facebook->api_client->users_setStatus(
 | 
				
			||||||
 | 
					         $text,
 | 
				
			||||||
 | 
					         $fbuid,
 | 
				
			||||||
 | 
					         false,
 | 
				
			||||||
 | 
					         true
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    common_debug('Facebook returned: ' . var_export($result, true));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    common_log(
 | 
				
			||||||
 | 
					        LOG_INFO,
 | 
				
			||||||
 | 
					        "FacebookPlugin - Posted notice $notice->id as a status "
 | 
				
			||||||
 | 
					        . "update for $user->nickname ($user->id), "
 | 
				
			||||||
 | 
					        . "Facebook UID: $fbuid"
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function publishStream($notice, $user, $fbuid)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    common_debug(
 | 
				
			||||||
 | 
					        "FacebookPlugin - Attempting to post notice $notice->id "
 | 
				
			||||||
 | 
					        . "as stream item with attachment for $user->nickname ($user->id), "
 | 
				
			||||||
 | 
					        . "Facebook UID: $fbuid"
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $text = formatNotice($notice, $user, $fbuid);
 | 
				
			||||||
 | 
					    $fbattachment = format_attachments($notice->attachments());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $facebook = getFacebook();
 | 
				
			||||||
 | 
					    $facebook->api_client->stream_publish(
 | 
				
			||||||
 | 
					        $text,
 | 
				
			||||||
 | 
					        $fbattachment,
 | 
				
			||||||
 | 
					        null,
 | 
				
			||||||
 | 
					        null,
 | 
				
			||||||
 | 
					        $fbuid
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    common_log(
 | 
				
			||||||
 | 
					        LOG_INFO,
 | 
				
			||||||
 | 
					        "FacebookPlugin - Posted notice $notice->id as a stream "
 | 
				
			||||||
 | 
					        . "item with attachment for $user->nickname ($user->id), "
 | 
				
			||||||
 | 
					        . "Facebook UID: $fbuid"
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function formatNotice($notice, $user, $fbuid)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // Get the status 'verb' the user has set, if any
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    common_debug(
 | 
				
			||||||
 | 
					        "FacebookPlugin - Looking to see if $user->nickname ($user->id), "
 | 
				
			||||||
 | 
					        . "Facebook UID: $fbuid has set a verb for Facebook posting..."
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $facebook = getFacebook();
 | 
				
			||||||
 | 
					    $verb = trim(
 | 
				
			||||||
 | 
					        $facebook->api_client->data_getUserPreference(
 | 
				
			||||||
 | 
					            FACEBOOK_NOTICE_PREFIX,
 | 
				
			||||||
 | 
					            $fbuid
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    common_debug("Facebook returned " . var_export($verb, true));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $text = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!empty($verb)) {
 | 
				
			||||||
 | 
					        common_debug("FacebookPlugin - found a verb: $verb");
 | 
				
			||||||
 | 
					        $text = trim($verb) . ' ' . $notice->content;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
 | 
					        common_debug("FacebookPlugin - no verb found.");
 | 
				
			||||||
                // Try sending again later.
 | 
					        $text = $notice->content;
 | 
				
			||||||
                //
 | 
					 | 
				
			||||||
                // @fixme at the moment, returning false here could lead to an infinite loop
 | 
					 | 
				
			||||||
                // if the error condition isn't actually transitory.
 | 
					 | 
				
			||||||
                //
 | 
					 | 
				
			||||||
                // Temporarily throwing an exception to kill the process so it'll hit our
 | 
					 | 
				
			||||||
                // retry limits.
 | 
					 | 
				
			||||||
                throw new Exception("Facebook error $code on notice $notice->id");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                return false;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					    return $text;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return true;
 | 
					function updateProfileBox($facebook, $flink, $notice, $user) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					    $facebook = getFacebook();
 | 
				
			||||||
 | 
					    $fbaction = new FacebookAction(
 | 
				
			||||||
 | 
					        $output = 'php://output',
 | 
				
			||||||
 | 
					        $indent = null,
 | 
				
			||||||
 | 
					        $facebook,
 | 
				
			||||||
 | 
					        $flink
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $fbuid = $flink->foreign_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    common_debug(
 | 
				
			||||||
 | 
					          'FacebookPlugin - Attempting to update profile box with '
 | 
				
			||||||
 | 
					          . "content from notice $notice->id for $user->nickname ($user->id), "
 | 
				
			||||||
 | 
					          . "Facebook UID: $fbuid"
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function updateProfileBox($facebook, $flink, $notice) {
 | 
					 | 
				
			||||||
    $fbaction = new FacebookAction($output = 'php://output',
 | 
					 | 
				
			||||||
                                   $indent = null, $facebook, $flink);
 | 
					 | 
				
			||||||
    $fbaction->updateProfileBox($notice);
 | 
					    $fbaction->updateProfileBox($notice);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    common_debug(
 | 
				
			||||||
 | 
					        'FacebookPlugin - finished updating profile box for '
 | 
				
			||||||
 | 
					        . "$user->nickname ($user->id) Facebook UID: $fbuid"
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function format_attachments($attachments)
 | 
					function format_attachments($attachments)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user