- Map notices to Facebook stream items
- rename plugin FacebookBridgePlugin - delete/like/unlike notices across the bridge
This commit is contained in:
		@@ -45,10 +45,9 @@ define("FACEBOOK_SERVICE", 2);
 | 
				
			|||||||
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
 | 
					 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
 | 
				
			||||||
 * @link      http://status.net/
 | 
					 * @link      http://status.net/
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
class FacebookSSOPlugin extends Plugin
 | 
					class FacebookBridgePlugin extends Plugin
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public $appId    = null; // Facebook application ID
 | 
					    public $appId    = null; // Facebook application ID
 | 
				
			||||||
    public $apikey   = null; // Facebook API key (for deprecated "Old REST API")
 | 
					 | 
				
			||||||
    public $secret   = null; // Facebook application secret
 | 
					    public $secret   = null; // Facebook application secret
 | 
				
			||||||
    public $facebook = null; // Facebook application instance
 | 
					    public $facebook = null; // Facebook application instance
 | 
				
			||||||
    public $dir      = null; // Facebook SSO plugin dir
 | 
					    public $dir      = null; // Facebook SSO plugin dir
 | 
				
			||||||
@@ -64,7 +63,6 @@ class FacebookSSOPlugin extends Plugin
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->facebook = Facebookclient::getFacebook(
 | 
					        $this->facebook = Facebookclient::getFacebook(
 | 
				
			||||||
            $this->appId,
 | 
					            $this->appId,
 | 
				
			||||||
            $this->apikey,
 | 
					 | 
				
			||||||
            $this->secret
 | 
					            $this->secret
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -101,12 +99,32 @@ class FacebookSSOPlugin extends Plugin
 | 
				
			|||||||
        case 'FacebookQueueHandler':
 | 
					        case 'FacebookQueueHandler':
 | 
				
			||||||
            include_once $dir . '/lib/' . strtolower($cls) . '.php';
 | 
					            include_once $dir . '/lib/' . strtolower($cls) . '.php';
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
 | 
					        case 'Notice_to_item':
 | 
				
			||||||
 | 
					            include_once $dir . '/classes/' . $cls . '.php';
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
        default:
 | 
					        default:
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Database schema setup
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * We maintain a table mapping StatusNet notices to Facebook items
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @see Schema
 | 
				
			||||||
 | 
					     * @see ColumnDef
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return boolean hook value; true means continue processing, false means stop.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function onCheckSchema()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $schema = Schema::get();
 | 
				
			||||||
 | 
					        $schema->ensureTable('notice_to_item', Notice_to_item::schemaDef());
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*
 | 
					    /*
 | 
				
			||||||
     * Does this $action need the Facebook JavaScripts?
 | 
					     * Does this $action need the Facebook JavaScripts?
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
@@ -436,6 +454,54 @@ ENDOFSCRIPT;
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * If a notice gets deleted, remove the Notice_to_item mapping and
 | 
				
			||||||
 | 
					     * delete the item on Facebook
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param User   $user   The user doing the deleting
 | 
				
			||||||
 | 
					     * @param Notice $notice The notice getting deleted
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return boolean hook value
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function onStartDeleteOwnNotice(User $user, Notice $notice)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $client = new Facebookclient($notice);
 | 
				
			||||||
 | 
					        $client->streamRemove();
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Notify remote users when their notices get favorited.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param Profile or User $profile of local user doing the faving
 | 
				
			||||||
 | 
					     * @param Notice $notice being favored
 | 
				
			||||||
 | 
					     * @return hook return value
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function onEndFavorNotice(Profile $profile, Notice $notice)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $client = new Facebookclient($notice);
 | 
				
			||||||
 | 
					        $client->like();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Notify remote users when their notices get de-favorited.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param Profile $profile Profile person doing the de-faving
 | 
				
			||||||
 | 
					     * @param Notice  $notice  Notice being favored
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return hook return value
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function onEndDisfavorNotice(Profile $profile, Notice $notice)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $client = new Facebookclient($notice);
 | 
				
			||||||
 | 
					        $client->unLike();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*
 | 
					    /*
 | 
				
			||||||
     * Add version info for this plugin
 | 
					     * Add version info for this plugin
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
@@ -447,7 +513,7 @@ ENDOFSCRIPT;
 | 
				
			|||||||
            'name' => 'Facebook Single-Sign-On',
 | 
					            'name' => 'Facebook Single-Sign-On',
 | 
				
			||||||
            'version' => STATUSNET_VERSION,
 | 
					            'version' => STATUSNET_VERSION,
 | 
				
			||||||
            'author' => 'Craig Andrews, Zach Copley',
 | 
					            'author' => 'Craig Andrews, Zach Copley',
 | 
				
			||||||
            'homepage' => 'http://status.net/wiki/Plugin:FacebookSSO',
 | 
					            'homepage' => 'http://status.net/wiki/Plugin:FacebookBridge',
 | 
				
			||||||
            'rawdescription' =>
 | 
					            'rawdescription' =>
 | 
				
			||||||
            _m('A plugin for integrating StatusNet with Facebook.')
 | 
					            _m('A plugin for integrating StatusNet with Facebook.')
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
@@ -112,7 +112,7 @@ class FacebookdeauthorizeAction extends Action
 | 
				
			|||||||
                common_log(
 | 
					                common_log(
 | 
				
			||||||
                    LOG_WARNING,
 | 
					                    LOG_WARNING,
 | 
				
			||||||
                    sprintf(
 | 
					                    sprintf(
 | 
				
			||||||
                        '%s (%d), fbuid $s has deauthorized his/her Facebook '
 | 
					                        '%s (%d), fbuid %d has deauthorized his/her Facebook '
 | 
				
			||||||
                        . 'connection but hasn\'t set a password so s/he '
 | 
					                        . 'connection but hasn\'t set a password so s/he '
 | 
				
			||||||
                        . 'is locked out.',
 | 
					                        . 'is locked out.',
 | 
				
			||||||
                        $user->nickname,
 | 
					                        $user->nickname,
 | 
				
			||||||
@@ -135,8 +135,8 @@ class FacebookdeauthorizeAction extends Action
 | 
				
			|||||||
                );
 | 
					                );
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                // It probably wasn't Facebook that hit this action,
 | 
					                // It probably wasn't Facebook that hit this action,
 | 
				
			||||||
                // so redirect to the login page
 | 
					                // so redirect to the public timeline
 | 
				
			||||||
                common_redirect(common_local_url('login'), 303);
 | 
					                common_redirect(common_local_url('public'), 303);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -126,12 +126,20 @@ class FacebookfinishloginAction extends Action
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
 | 
					        } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
 | 
				
			||||||
 | 
					            $this->handlePost();
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $this->tryLogin();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function handlePost()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        $token = $this->trimmed('token');
 | 
					        $token = $this->trimmed('token');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!$token || $token != common_session_token()) {
 | 
					        if (!$token || $token != common_session_token()) {
 | 
				
			||||||
            $this->showForm(
 | 
					            $this->showForm(
 | 
				
			||||||
                    _m('There was a problem with your session token. Try again, please.'));
 | 
					                _m('There was a problem with your session token. Try again, please.')
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -160,10 +168,6 @@ class FacebookfinishloginAction extends Action
 | 
				
			|||||||
                $this->trimmed('newname')
 | 
					                $this->trimmed('newname')
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            $this->tryLogin();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function showPageNotice()
 | 
					    function showPageNotice()
 | 
				
			||||||
@@ -343,19 +347,23 @@ class FacebookfinishloginAction extends Action
 | 
				
			|||||||
            'nickname'        => $nickname,
 | 
					            'nickname'        => $nickname,
 | 
				
			||||||
            'fullname'        => $this->fbuser['first_name']
 | 
					            'fullname'        => $this->fbuser['first_name']
 | 
				
			||||||
                . ' ' . $this->fbuser['last_name'],
 | 
					                . ' ' . $this->fbuser['last_name'],
 | 
				
			||||||
            'email'           => $this->fbuser['email'],
 | 
					 | 
				
			||||||
            'email_confirmed' => true,
 | 
					 | 
				
			||||||
            'homepage'        => $this->fbuser['website'],
 | 
					            'homepage'        => $this->fbuser['website'],
 | 
				
			||||||
            'bio'             => $this->fbuser['about'],
 | 
					            'bio'             => $this->fbuser['about'],
 | 
				
			||||||
            'location'        => $this->fbuser['location']['name']
 | 
					            'location'        => $this->fbuser['location']['name']
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // It's possible that the email address is already in our
 | 
				
			||||||
 | 
					        // DB. It's a unique key, so we need to check
 | 
				
			||||||
 | 
					        if ($this->isNewEmail($this->fbuser['email'])) {
 | 
				
			||||||
 | 
					            $args['email']           = $this->fbuser['email'];
 | 
				
			||||||
 | 
					            $args['email_confirmed'] = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!empty($invite)) {
 | 
					        if (!empty($invite)) {
 | 
				
			||||||
            $args['code'] = $invite->code;
 | 
					            $args['code'] = $invite->code;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $user   = User::register($args);
 | 
					        $user   = User::register($args);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        $result = $this->flinkUser($user->id, $this->fbuid);
 | 
					        $result = $this->flinkUser($user->id, $this->fbuid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!$result) {
 | 
					        if (!$result) {
 | 
				
			||||||
@@ -363,6 +371,9 @@ class FacebookfinishloginAction extends Action
 | 
				
			|||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Add a Foreign_user record
 | 
				
			||||||
 | 
					        Facebookclient::addFacebookUser($this->fbuser);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->setAvatar($user);
 | 
					        $this->setAvatar($user);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        common_set_user($user);
 | 
					        common_set_user($user);
 | 
				
			||||||
@@ -371,20 +382,16 @@ class FacebookfinishloginAction extends Action
 | 
				
			|||||||
        common_log(
 | 
					        common_log(
 | 
				
			||||||
            LOG_INFO,
 | 
					            LOG_INFO,
 | 
				
			||||||
            sprintf(
 | 
					            sprintf(
 | 
				
			||||||
                'Registered new user %d from Facebook user %s',
 | 
					                'Registered new user %s (%d) from Facebook user %s, (fbuid %d)',
 | 
				
			||||||
 | 
					                $user->nickname,
 | 
				
			||||||
                $user->id,
 | 
					                $user->id,
 | 
				
			||||||
 | 
					                $this->fbuser['name'],
 | 
				
			||||||
                $this->fbuid
 | 
					                $this->fbuid
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
            __FILE__
 | 
					            __FILE__
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        common_redirect(
 | 
					        $this->goHome($user->nickname);
 | 
				
			||||||
            common_local_url(
 | 
					 | 
				
			||||||
                'showstream',
 | 
					 | 
				
			||||||
                array('nickname' => $user->nickname)
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
            303
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*
 | 
					    /*
 | 
				
			||||||
@@ -401,17 +408,19 @@ class FacebookfinishloginAction extends Action
 | 
				
			|||||||
        // fetch the picture from Facebook
 | 
					        // fetch the picture from Facebook
 | 
				
			||||||
        $client = new HTTPClient();
 | 
					        $client = new HTTPClient();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        common_debug("status = $status - " . $finalUrl , __FILE__);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // fetch the actual picture
 | 
					        // fetch the actual picture
 | 
				
			||||||
        $response = $client->get($picUrl);
 | 
					        $response = $client->get($picUrl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($response->isOk()) {
 | 
					        if ($response->isOk()) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $finalUrl = $client->getUrl();
 | 
					            $finalUrl = $client->getUrl();
 | 
				
			||||||
            $filename = 'facebook-' . substr(strrchr($finalUrl, '/'), 1 );
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            common_debug("Filename = " . $filename, __FILE__);
 | 
					            // Make sure the filename is unique becuase it's possible for a user
 | 
				
			||||||
 | 
					            // to deauthorize our app, and then come back in as a new user but
 | 
				
			||||||
 | 
					            // have the same Facebook picture (avatar URLs have a unique index
 | 
				
			||||||
 | 
					            // and their URLs are based on the filenames).
 | 
				
			||||||
 | 
					            $filename = 'facebook-' . common_good_rand(4) . '-'
 | 
				
			||||||
 | 
					                . substr(strrchr($finalUrl, '/'), 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $ok = file_put_contents(
 | 
					            $ok = file_put_contents(
 | 
				
			||||||
                Avatar::path($filename),
 | 
					                Avatar::path($filename),
 | 
				
			||||||
@@ -430,17 +439,20 @@ class FacebookfinishloginAction extends Action
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // save it as an avatar
 | 
				
			||||||
                $profile = $user->getProfile();
 | 
					                $profile = $user->getProfile();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if ($profile->setOriginal($filename)) {
 | 
					                if ($profile->setOriginal($filename)) {
 | 
				
			||||||
                    common_log(
 | 
					                    common_log(
 | 
				
			||||||
                        LOG_INFO,
 | 
					                        LOG_INFO,
 | 
				
			||||||
                        sprintf(
 | 
					                        sprintf(
 | 
				
			||||||
                            'Saved avatar for %s (%d) from Facebook profile %s, filename = %s',
 | 
					                            'Saved avatar for %s (%d) from Facebook picture for '
 | 
				
			||||||
 | 
					                                . '%s (fbuid %d), filename = %s',
 | 
				
			||||||
                             $user->nickname,
 | 
					                             $user->nickname,
 | 
				
			||||||
                             $user->id,
 | 
					                             $user->id,
 | 
				
			||||||
 | 
					                             $this->fbuser['name'],
 | 
				
			||||||
                             $this->fbuid,
 | 
					                             $this->fbuid,
 | 
				
			||||||
                             $picture
 | 
					                             $filename
 | 
				
			||||||
                        ),
 | 
					                        ),
 | 
				
			||||||
                        __FILE__
 | 
					                        __FILE__
 | 
				
			||||||
                    );
 | 
					                    );
 | 
				
			||||||
@@ -462,19 +474,17 @@ class FacebookfinishloginAction extends Action
 | 
				
			|||||||
        $user = User::staticGet('nickname', $nickname);
 | 
					        $user = User::staticGet('nickname', $nickname);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!empty($user)) {
 | 
					        if (!empty($user)) {
 | 
				
			||||||
            common_debug('Facebook Connect Plugin - ' .
 | 
					            common_debug(
 | 
				
			||||||
                         "Legit user to connect to Facebook: $nickname");
 | 
					                sprintf(
 | 
				
			||||||
 | 
					                    'Found a legit user to connect to Facebook: %s (%d)',
 | 
				
			||||||
 | 
					                    $user->nickname,
 | 
				
			||||||
 | 
					                    $user->id
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					                __FILE__
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $result = $this->flinkUser($user->id, $this->fbuid);
 | 
					        $this->tryLinkUser($user);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (!$result) {
 | 
					 | 
				
			||||||
            $this->serverError(_m('Error connecting user to Facebook.'));
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        common_debug('Facebook Connnect Plugin - ' .
 | 
					 | 
				
			||||||
                     "Connected Facebook user $this->fbuid to local user $user->id");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        common_set_user($user);
 | 
					        common_set_user($user);
 | 
				
			||||||
        common_real_login(true);
 | 
					        common_real_login(true);
 | 
				
			||||||
@@ -485,7 +495,12 @@ class FacebookfinishloginAction extends Action
 | 
				
			|||||||
    function connectUser()
 | 
					    function connectUser()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $user = common_current_user();
 | 
					        $user = common_current_user();
 | 
				
			||||||
 | 
					        $this->tryLinkUser($user);
 | 
				
			||||||
 | 
					        common_redirect(common_local_url('facebookfinishlogin'), 303);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function tryLinkUser($user)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        $result = $this->flinkUser($user->id, $this->fbuid);
 | 
					        $result = $this->flinkUser($user->id, $this->fbuid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (empty($result)) {
 | 
					        if (empty($result)) {
 | 
				
			||||||
@@ -495,14 +510,14 @@ class FacebookfinishloginAction extends Action
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        common_debug(
 | 
					        common_debug(
 | 
				
			||||||
            sprintf(
 | 
					            sprintf(
 | 
				
			||||||
                'Connected Facebook user %s to local user %d',
 | 
					                'Connected Facebook user %s (fbuid %d) to local user %s (%d)',
 | 
				
			||||||
 | 
					                $this->fbuser['name'],
 | 
				
			||||||
                $this->fbuid,
 | 
					                $this->fbuid,
 | 
				
			||||||
 | 
					                $user->nickname,
 | 
				
			||||||
                $user->id
 | 
					                $user->id
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
            __FILE__
 | 
					            __FILE__
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					 | 
				
			||||||
        common_redirect(common_local_url('facebookfinishlogin'), 303);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function tryLogin()
 | 
					    function tryLogin()
 | 
				
			||||||
@@ -595,8 +610,8 @@ class FacebookfinishloginAction extends Action
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        // Try the full name
 | 
					        // Try the full name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $fullname = trim($this->fbuser['firstname'] .
 | 
					        $fullname = trim($this->fbuser['first_name'] .
 | 
				
			||||||
            ' ' . $this->fbuser['lastname']);
 | 
					            ' ' . $this->fbuser['last_name']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!empty($fullname)) {
 | 
					        if (!empty($fullname)) {
 | 
				
			||||||
            $fullname = $this->nicknamize($fullname);
 | 
					            $fullname = $this->nicknamize($fullname);
 | 
				
			||||||
@@ -617,20 +632,57 @@ class FacebookfinishloginAction extends Action
 | 
				
			|||||||
         return strtolower($str);
 | 
					         return strtolower($str);
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     /*
 | 
				
			||||||
 | 
					      * Is the desired nickname already taken?
 | 
				
			||||||
 | 
					      *
 | 
				
			||||||
 | 
					      * @return boolean result
 | 
				
			||||||
 | 
					      */
 | 
				
			||||||
     function isNewNickname($str)
 | 
					     function isNewNickname($str)
 | 
				
			||||||
     {
 | 
					     {
 | 
				
			||||||
        if (!Validate::string($str, array('min_length' => 1,
 | 
					        if (
 | 
				
			||||||
 | 
					            !Validate::string(
 | 
				
			||||||
 | 
					                $str,
 | 
				
			||||||
 | 
					                array(
 | 
				
			||||||
 | 
					                    'min_length' => 1,
 | 
				
			||||||
                    'max_length' => 64,
 | 
					                    'max_length' => 64,
 | 
				
			||||||
                                          'format' => NICKNAME_FMT))) {
 | 
					                    'format' => NICKNAME_FMT
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        ) {
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!User::allowed_nickname($str)) {
 | 
					        if (!User::allowed_nickname($str)) {
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (User::staticGet('nickname', $str)) {
 | 
					        if (User::staticGet('nickname', $str)) {
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * Do we already have a user record with this email?
 | 
				
			||||||
 | 
					     * (emails have to be unique but they can change)
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param string $email the email address to check
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return boolean result
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					     function isNewEmail($email)
 | 
				
			||||||
 | 
					     {
 | 
				
			||||||
 | 
					         // we shouldn't have to validate the format
 | 
				
			||||||
 | 
					         $result = User::staticGet('email', $email);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         if (empty($result)) {
 | 
				
			||||||
 | 
					             common_debug("XXXXXXXXXXXXXXXXXX We've never seen this email before!!!");
 | 
				
			||||||
 | 
					             return true;
 | 
				
			||||||
 | 
					         }
 | 
				
			||||||
 | 
					         common_debug("XXXXXXXXXXXXXXXXXX dupe email address!!!!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         return false;
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -89,7 +89,7 @@ class FacebookloginAction extends Action
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $attrs = array(
 | 
					        $attrs = array(
 | 
				
			||||||
            'src' => common_path(
 | 
					            'src' => common_path(
 | 
				
			||||||
                'plugins/FacebookSSO/images/login-button.png',
 | 
					                'plugins/FacebookBridge/images/login-button.png',
 | 
				
			||||||
                true
 | 
					                true
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
            'alt'   => 'Login with Facebook',
 | 
					            'alt'   => 'Login with Facebook',
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										190
									
								
								plugins/FacebookSSO/classes/Notice_to_item.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										190
									
								
								plugins/FacebookSSO/classes/Notice_to_item.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,190 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Data class for storing notice-to-Facebook-item mappings
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * PHP version 5
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @category Data
 | 
				
			||||||
 | 
					 * @package  StatusNet
 | 
				
			||||||
 | 
					 * @author   Zach Copley <zach@status.net>
 | 
				
			||||||
 | 
					 * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
 | 
				
			||||||
 | 
					 * @link     http://status.net/
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * StatusNet - the distributed open-source microblogging tool
 | 
				
			||||||
 | 
					 * Copyright (C) 2010, StatusNet, Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU Affero General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.     See the
 | 
				
			||||||
 | 
					 * GNU Affero General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Affero General Public License
 | 
				
			||||||
 | 
					 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!defined('STATUSNET')) {
 | 
				
			||||||
 | 
					    exit(1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require_once INSTALLDIR . '/classes/Memcached_DataObject.php';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Data class for mapping notices to Facebook stream items
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Note that notice_id is unique only within a single database; if you
 | 
				
			||||||
 | 
					 * want to share this data for some reason, get the notice's URI and use
 | 
				
			||||||
 | 
					 * that instead, since it's universally unique.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @category Action
 | 
				
			||||||
 | 
					 * @package  StatusNet
 | 
				
			||||||
 | 
					 * @author   Zach Copley <zach@status.net>
 | 
				
			||||||
 | 
					 * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
 | 
				
			||||||
 | 
					 * @link     http://status.net/
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @see      DB_DataObject
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Notice_to_item extends Memcached_DataObject
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public $__table = 'notice_to_item'; // table name
 | 
				
			||||||
 | 
					    public $notice_id;                  // int(4)  primary_key not_null
 | 
				
			||||||
 | 
					    public $item_id;                    // varchar(255) not null
 | 
				
			||||||
 | 
					    public $created;                    // datetime
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Get an instance by key
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * This is a utility method to get a single instance with a given key value.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param string $k Key to use to lookup
 | 
				
			||||||
 | 
					     * @param mixed  $v Value to lookup
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Notice_to_item object found, or null for no hits
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function staticGet($k, $v=null)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return Memcached_DataObject::staticGet('Notice_to_item', $k, $v);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * return table definition for DB_DataObject
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * DB_DataObject needs to know something about the table to manipulate
 | 
				
			||||||
 | 
					     * instances. This method provides all the DB_DataObject needs to know.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return array array of column definitions
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function table()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return array(
 | 
				
			||||||
 | 
					            'notice_id' => DB_DATAOBJECT_INT + DB_DATAOBJECT_NOTNULL,
 | 
				
			||||||
 | 
					            'item_id'   => DB_DATAOBJECT_STR + DB_DATAOBJECT_NOTNULL,
 | 
				
			||||||
 | 
					            'created'   => DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME + DB_DATAOBJECT_NOTNULL
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static function schemaDef()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return array(
 | 
				
			||||||
 | 
					            new ColumnDef('notice_id', 'integer', null, false, 'PRI'),
 | 
				
			||||||
 | 
					            new ColumnDef('item_id', 'varchar', 255, false, 'UNI'),
 | 
				
			||||||
 | 
					            new ColumnDef('created', 'datetime',  null, false)
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * return key definitions for DB_DataObject
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * DB_DataObject needs to know about keys that the table has, since it
 | 
				
			||||||
 | 
					     * won't appear in StatusNet's own keys list. In most cases, this will
 | 
				
			||||||
 | 
					     * simply reference your keyTypes() function.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return array list of key field names
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function keys()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return array_keys($this->keyTypes());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * return key definitions for Memcached_DataObject
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Our caching system uses the same key definitions, but uses a different
 | 
				
			||||||
 | 
					     * method to get them. This key information is used to store and clear
 | 
				
			||||||
 | 
					     * cached data, so be sure to list any key that will be used for static
 | 
				
			||||||
 | 
					     * lookups.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return array associative array of key definitions, field name to type:
 | 
				
			||||||
 | 
					     *         'K' for primary key: for compound keys, add an entry for each component;
 | 
				
			||||||
 | 
					     *         'U' for unique keys: compound keys are not well supported here.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function keyTypes()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return array('notice_id' => 'K', 'item_id' => 'U');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Magic formula for non-autoincrementing integer primary keys
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * If a table has a single integer column as its primary key, DB_DataObject
 | 
				
			||||||
 | 
					     * assumes that the column is auto-incrementing and makes a sequence table
 | 
				
			||||||
 | 
					     * to do this incrementation. Since we don't need this for our class, we
 | 
				
			||||||
 | 
					     * overload this method and return the magic formula that DB_DataObject needs.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return array magic three-false array that stops auto-incrementing.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function sequenceKey()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return array(false, false, false);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Save a mapping between a notice and a Facebook item
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param integer $notice_id ID of the notice in StatusNet
 | 
				
			||||||
 | 
					     * @param integer $item_id ID of the stream item on Facebook
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return Notice_to_item new object for this value
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static function saveNew($notice_id, $item_id)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $n2i = Notice_to_item::staticGet('notice_id', $notice_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!empty($n2i)) {
 | 
				
			||||||
 | 
					            return $n2i;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $n2i = Notice_to_item::staticGet('item_id', $item_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!empty($n2i)) {
 | 
				
			||||||
 | 
					            return $n2i;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        common_debug(
 | 
				
			||||||
 | 
					            "Mapping notice {$notice_id} to Facebook item {$item_id}",
 | 
				
			||||||
 | 
					            __FILE__
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $n2i = new Notice_to_item();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $n2i->notice_id = $notice_id;
 | 
				
			||||||
 | 
					        $n2i->item_id   = $item_id;
 | 
				
			||||||
 | 
					        $n2i->created   = common_sql_now();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $n2i->insert();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $n2i;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -173,11 +173,11 @@ class Facebookclient
 | 
				
			|||||||
        if ($this->isFacebookBound()) {
 | 
					        if ($this->isFacebookBound()) {
 | 
				
			||||||
            common_debug("notice is facebook bound", __FILE__);
 | 
					            common_debug("notice is facebook bound", __FILE__);
 | 
				
			||||||
            if (empty($this->flink->credentials)) {
 | 
					            if (empty($this->flink->credentials)) {
 | 
				
			||||||
                $this->sendOldRest();
 | 
					                return $this->sendOldRest();
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // Otherwise we most likely have an access token
 | 
					                // Otherwise we most likely have an access token
 | 
				
			||||||
                $this->sendGraph();
 | 
					                return $this->sendGraph();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
@@ -213,6 +213,7 @@ class Facebookclient
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            $params = array(
 | 
					            $params = array(
 | 
				
			||||||
                'access_token' => $this->flink->credentials,
 | 
					                'access_token' => $this->flink->credentials,
 | 
				
			||||||
 | 
					                // XXX: Need to worrry about length of the message?
 | 
				
			||||||
                'message'      => $this->notice->content
 | 
					                'message'      => $this->notice->content
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -220,7 +221,7 @@ class Facebookclient
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            if (!empty($attachments)) {
 | 
					            if (!empty($attachments)) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // We can only send one attachment with the Graph API
 | 
					                // We can only send one attachment with the Graph API :(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                $first = array_shift($attachments);
 | 
					                $first = array_shift($attachments);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -240,6 +241,21 @@ class Facebookclient
 | 
				
			|||||||
                sprintf('/%s/feed', $fbuid), 'post', $params
 | 
					                sprintf('/%s/feed', $fbuid), 'post', $params
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Save a mapping
 | 
				
			||||||
 | 
					            Notice_to_item::saveNew($this->notice->id, $result['id']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            common_log(
 | 
				
			||||||
 | 
					                LOG_INFO,
 | 
				
			||||||
 | 
					                sprintf(
 | 
				
			||||||
 | 
					                    "Posted notice %d as a stream item for %s (%d), fbuid %s",
 | 
				
			||||||
 | 
					                    $this->notice->id,
 | 
				
			||||||
 | 
					                    $this->user->nickname,
 | 
				
			||||||
 | 
					                    $this->user->id,
 | 
				
			||||||
 | 
					                    $fbuid
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					                __FILE__
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        } catch (FacebookApiException $e) {
 | 
					        } catch (FacebookApiException $e) {
 | 
				
			||||||
            return $this->handleFacebookError($e);
 | 
					            return $this->handleFacebookError($e);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -481,12 +497,14 @@ class Facebookclient
 | 
				
			|||||||
        $result = $this->facebook->api(
 | 
					        $result = $this->facebook->api(
 | 
				
			||||||
            array(
 | 
					            array(
 | 
				
			||||||
                'method'               => 'users.setStatus',
 | 
					                'method'               => 'users.setStatus',
 | 
				
			||||||
                'status'               => $this->notice->content,
 | 
					                'status'               => $this->formatMessage(),
 | 
				
			||||||
                'status_includes_verb' => true,
 | 
					                'status_includes_verb' => true,
 | 
				
			||||||
                'uid'                  => $fbuid
 | 
					                'uid'                  => $fbuid
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($result == 1) { // 1 is success
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            common_log(
 | 
					            common_log(
 | 
				
			||||||
                LOG_INFO,
 | 
					                LOG_INFO,
 | 
				
			||||||
                sprintf(
 | 
					                sprintf(
 | 
				
			||||||
@@ -499,6 +517,22 @@ class Facebookclient
 | 
				
			|||||||
                __FILE__
 | 
					                __FILE__
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // There is no item ID returned for status update so we can't
 | 
				
			||||||
 | 
					            // save a Notice_to_item mapping
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $msg = sprintf(
 | 
				
			||||||
 | 
					                "Error posting notice %s as a status update for %s (%d), fbuid %s - error code: %s",
 | 
				
			||||||
 | 
					                $this->notice->id,
 | 
				
			||||||
 | 
					                $this->user->nickname,
 | 
				
			||||||
 | 
					                $this->user->id,
 | 
				
			||||||
 | 
					                $fbuid,
 | 
				
			||||||
 | 
					                $result // will contain 0, or an error
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            throw new FacebookApiException($msg, $result);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*
 | 
					    /*
 | 
				
			||||||
@@ -524,12 +558,17 @@ class Facebookclient
 | 
				
			|||||||
        $result = $this->facebook->api(
 | 
					        $result = $this->facebook->api(
 | 
				
			||||||
            array(
 | 
					            array(
 | 
				
			||||||
                'method'     => 'stream.publish',
 | 
					                'method'     => 'stream.publish',
 | 
				
			||||||
                'message'    => $this->notice->content,
 | 
					                'message'    => $this->formatMessage(),
 | 
				
			||||||
                'attachment' => $fbattachment,
 | 
					                'attachment' => $fbattachment,
 | 
				
			||||||
                'uid'        => $fbuid
 | 
					                'uid'        => $fbuid
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!empty($result)) { // result will contain the item ID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Save a mapping
 | 
				
			||||||
 | 
					            Notice_to_item::saveNew($this->notice->id, $result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            common_log(
 | 
					            common_log(
 | 
				
			||||||
                LOG_INFO,
 | 
					                LOG_INFO,
 | 
				
			||||||
                sprintf(
 | 
					                sprintf(
 | 
				
			||||||
@@ -543,6 +582,42 @@ class Facebookclient
 | 
				
			|||||||
                __FILE__
 | 
					                __FILE__
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $msg = sprintf(
 | 
				
			||||||
 | 
					                'Could not post notice %d as a %s for %s (%d), fbuid %s - error code: %s',
 | 
				
			||||||
 | 
					                $this->notice->id,
 | 
				
			||||||
 | 
					                empty($fbattachment) ? 'stream item' : 'stream item with attachment',
 | 
				
			||||||
 | 
					                $this->user->nickname,
 | 
				
			||||||
 | 
					                $this->user->id,
 | 
				
			||||||
 | 
					                $result, // result will contain an error code
 | 
				
			||||||
 | 
					                $fbuid
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            throw new FacebookApiException($msg, $result);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * Format the text message of a stream item so it's appropriate for
 | 
				
			||||||
 | 
					     * sending to Facebook. If the notice is too long, truncate it, and
 | 
				
			||||||
 | 
					     * add a linkback to the original notice at the end.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return String $txt the formated message
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function formatMessage()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // Start with the plaintext source of this notice...
 | 
				
			||||||
 | 
					        $txt = $this->notice->content;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Facebook has a 420-char hardcoded max.
 | 
				
			||||||
 | 
					        if (mb_strlen($statustxt) > 420) {
 | 
				
			||||||
 | 
					            $noticeUrl = common_shorten_url($this->notice->uri);
 | 
				
			||||||
 | 
					            $urlLen = mb_strlen($noticeUrl);
 | 
				
			||||||
 | 
					            $txt = mb_substr($statustxt, 0, 420 - ($urlLen + 3)) . ' … ' . $noticeUrl;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $txt;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /*
 | 
					    /*
 | 
				
			||||||
@@ -708,4 +783,240 @@ BODY;
 | 
				
			|||||||
        return mail_to_user($this->user, $subject, $body);
 | 
					        return mail_to_user($this->user, $subject, $body);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * Check to see if we have a mapping to a copy of this notice
 | 
				
			||||||
 | 
					     * on Facebook
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param Notice $notice the notice to check
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return mixed null if it can't find one, or the id of the Facebook
 | 
				
			||||||
 | 
					     *               stream item
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    static function facebookStatusId($notice)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $n2i = Notice_to_item::staticGet('notice_id', $notice->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (empty($n2i)) {
 | 
				
			||||||
 | 
					            return null;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            return $n2i->item_id;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * Save a Foreign_user record of a Facebook user
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param object $fbuser a Facebook Graph API user obj
 | 
				
			||||||
 | 
					     *                       See: http://developers.facebook.com/docs/reference/api/user
 | 
				
			||||||
 | 
					     * @return mixed $result Id or key
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    static function addFacebookUser($fbuser)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // remove any existing, possibly outdated, record
 | 
				
			||||||
 | 
					        $luser = Foreign_user::getForeignUser($fbuser['id'], FACEBOOK_SERVICE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!empty($luser)) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $result = $luser->delete();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($result != false) {
 | 
				
			||||||
 | 
					                common_log(
 | 
				
			||||||
 | 
					                    LOG_INFO,
 | 
				
			||||||
 | 
					                    sprintf(
 | 
				
			||||||
 | 
					                        'Removed old Facebook user: %s, fbuid %d',
 | 
				
			||||||
 | 
					                        $fbuid['name'],
 | 
				
			||||||
 | 
					                        $fbuid['id']
 | 
				
			||||||
 | 
					                    ),
 | 
				
			||||||
 | 
					                    __FILE__
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $fuser = new Foreign_user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $fuser->nickname = $fbuser['name'];
 | 
				
			||||||
 | 
					        $fuser->uri      = $fbuser['link'];
 | 
				
			||||||
 | 
					        $fuser->id       = $fbuser['id'];
 | 
				
			||||||
 | 
					        $fuser->service  = FACEBOOK_SERVICE;
 | 
				
			||||||
 | 
					        $fuser->created  = common_sql_now();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $result = $fuser->insert();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (empty($result)) {
 | 
				
			||||||
 | 
					            common_log(
 | 
				
			||||||
 | 
					                LOG_WARNING,
 | 
				
			||||||
 | 
					                    sprintf(
 | 
				
			||||||
 | 
					                        'Failed to add new Facebook user: %s, fbuid %d',
 | 
				
			||||||
 | 
					                        $fbuser['name'],
 | 
				
			||||||
 | 
					                        $fbuser['id']
 | 
				
			||||||
 | 
					                    ),
 | 
				
			||||||
 | 
					                    __FILE__
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            common_log_db_error($fuser, 'INSERT', __FILE__);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            common_log(
 | 
				
			||||||
 | 
					                LOG_INFO,
 | 
				
			||||||
 | 
					                sprintf(
 | 
				
			||||||
 | 
					                    'Added new Facebook user: %s, fbuid %d',
 | 
				
			||||||
 | 
					                    $fbuser['name'],
 | 
				
			||||||
 | 
					                    $fbuser['id']
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					                __FILE__
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $result;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * Remove an item from a Facebook user's feed if we have a mapping
 | 
				
			||||||
 | 
					     * for it.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function streamRemove()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $n2i = Notice_to_item::staticGet('notice_id', $this->notice->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!empty($this->flink) && !empty($n2i)) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $result = $this->facebook->api(
 | 
				
			||||||
 | 
					                array(
 | 
				
			||||||
 | 
					                    'method'  => 'stream.remove',
 | 
				
			||||||
 | 
					                    'post_id' => $n2i->item_id,
 | 
				
			||||||
 | 
					                    'uid'     => $this->flink->foreign_id
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!empty($result) && result == true) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                common_log(
 | 
				
			||||||
 | 
					                  LOG_INFO,
 | 
				
			||||||
 | 
					                    sprintf(
 | 
				
			||||||
 | 
					                        'Deleted Facebook item: %s for %s (%d), fbuid %d',
 | 
				
			||||||
 | 
					                        $n2i->item_id,
 | 
				
			||||||
 | 
					                        $this->user->nickname,
 | 
				
			||||||
 | 
					                        $this->user->id,
 | 
				
			||||||
 | 
					                        $this->flink->foreign_id
 | 
				
			||||||
 | 
					                    ),
 | 
				
			||||||
 | 
					                    __FILE__
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $n2i->delete();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                common_log(
 | 
				
			||||||
 | 
					                  LOG_WARNING,
 | 
				
			||||||
 | 
					                    sprintf(
 | 
				
			||||||
 | 
					                        'Could not deleted Facebook item: %s for %s (%d), fbuid %d',
 | 
				
			||||||
 | 
					                        $n2i->item_id,
 | 
				
			||||||
 | 
					                        $this->user->nickname,
 | 
				
			||||||
 | 
					                        $this->user->id,
 | 
				
			||||||
 | 
					                        $this->flink->foreign_id
 | 
				
			||||||
 | 
					                    ),
 | 
				
			||||||
 | 
					                    __FILE__
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * Like an item in a Facebook user's feed if we have a mapping
 | 
				
			||||||
 | 
					     * for it.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function like()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $n2i = Notice_to_item::staticGet('notice_id', $this->notice->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!empty($this->flink) && !empty($n2i)) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $result = $this->facebook->api(
 | 
				
			||||||
 | 
					                array(
 | 
				
			||||||
 | 
					                    'method'  => 'stream.addlike',
 | 
				
			||||||
 | 
					                    'post_id' => $n2i->item_id,
 | 
				
			||||||
 | 
					                    'uid'     => $this->flink->foreign_id
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!empty($result) && result == true) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                common_log(
 | 
				
			||||||
 | 
					                  LOG_INFO,
 | 
				
			||||||
 | 
					                    sprintf(
 | 
				
			||||||
 | 
					                        'Added like for item: %s for %s (%d), fbuid %d',
 | 
				
			||||||
 | 
					                        $n2i->item_id,
 | 
				
			||||||
 | 
					                        $this->user->nickname,
 | 
				
			||||||
 | 
					                        $this->user->id,
 | 
				
			||||||
 | 
					                        $this->flink->foreign_id
 | 
				
			||||||
 | 
					                    ),
 | 
				
			||||||
 | 
					                    __FILE__
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                common_log(
 | 
				
			||||||
 | 
					                  LOG_WARNING,
 | 
				
			||||||
 | 
					                    sprintf(
 | 
				
			||||||
 | 
					                        'Could not like Facebook item: %s for %s (%d), fbuid %d',
 | 
				
			||||||
 | 
					                        $n2i->item_id,
 | 
				
			||||||
 | 
					                        $this->user->nickname,
 | 
				
			||||||
 | 
					                        $this->user->id,
 | 
				
			||||||
 | 
					                        $this->flink->foreign_id
 | 
				
			||||||
 | 
					                    ),
 | 
				
			||||||
 | 
					                    __FILE__
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * Unlike an item in a Facebook user's feed if we have a mapping
 | 
				
			||||||
 | 
					     * for it.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    function unLike()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $n2i = Notice_to_item::staticGet('notice_id', $this->notice->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!empty($this->flink) && !empty($n2i)) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $result = $this->facebook->api(
 | 
				
			||||||
 | 
					                array(
 | 
				
			||||||
 | 
					                    'method'  => 'stream.removeLike',
 | 
				
			||||||
 | 
					                    'post_id' => $n2i->item_id,
 | 
				
			||||||
 | 
					                    'uid'     => $this->flink->foreign_id
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!empty($result) && result == true) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                common_log(
 | 
				
			||||||
 | 
					                  LOG_INFO,
 | 
				
			||||||
 | 
					                    sprintf(
 | 
				
			||||||
 | 
					                        'Removed like for item: %s for %s (%d), fbuid %d',
 | 
				
			||||||
 | 
					                        $n2i->item_id,
 | 
				
			||||||
 | 
					                        $this->user->nickname,
 | 
				
			||||||
 | 
					                        $this->user->id,
 | 
				
			||||||
 | 
					                        $this->flink->foreign_id
 | 
				
			||||||
 | 
					                    ),
 | 
				
			||||||
 | 
					                    __FILE__
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                common_log(
 | 
				
			||||||
 | 
					                  LOG_WARNING,
 | 
				
			||||||
 | 
					                    sprintf(
 | 
				
			||||||
 | 
					                        'Could not remove like for Facebook item: %s for %s (%d), fbuid %d',
 | 
				
			||||||
 | 
					                        $n2i->item_id,
 | 
				
			||||||
 | 
					                        $this->user->nickname,
 | 
				
			||||||
 | 
					                        $this->user->id,
 | 
				
			||||||
 | 
					                        $this->flink->foreign_id
 | 
				
			||||||
 | 
					                    ),
 | 
				
			||||||
 | 
					                    __FILE__
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user