1

我正在为 PHP 使用 Facebook SDK。几个月前,当 Facebook 提出要求时,我已经为新的 Facebook SDK 实现了一些帮助类。我对结果总体感到满意。但是,我在异常日志中看到了一个奇怪的异常,我并不真正理解它。这些助手类之一是:

namespace Facebook\FacebookAccessor;
use Facebook\FacebookSession;
use Facebook\FacebookRequest;
use User;
use App;

class FacebookActionPrivilege {

    public static $ACTION_LOGIN_KEY = "login";
    public static $ACTION_LOGOUT_KEY = "logout";
    public static $ACTION_POST_KEY = "post";
    public static $ACTION_FIND_FRIENDS_KEY = "find_friends";
    public static $ACTION_PICTURE_KEY = "picture";

    public static $PRIVILEGE_PUBLIC_PROFILE_KEY = "public_profile";
    public static $PRIVILEGE_FIND_FRIENDS_KEY = "user_friends";
    public static $PRIVILEGE_EMAIL_KEY = "email";
    public static $PRIVILEGE_USER_PHOTOS_KEY = "user_photos";
    public static $PRIVILEGE_PUBLISH_ACTIONS_KEY = "publish_actions";

    private static $initialized = false;
    private static $session;
    private static $isSessionValid = false;
    private static $distantPrivileges = null;

    private static $facebookActionPrivileges = array();

    public static function getSession() {
        return self::$session;
    }

    public static function getDistantPrivileges() {
        if (!self::$session) {
            return array();
        }
        if (self::$distantPrivileges === null) {
            $request = new FacebookRequest(
              FacebookActionPrivilege::getSession(),
              'GET',
              '/me/permissions'
            );
            self::$distantPrivileges = $request->execute()->getResponse()->data; //Line 44
        }
        return self::$distantPrivileges;
    }

    public static function init() {
        FacebookSession::setDefaultApplication(App::env()->get('facebook', 'appId'), App::env()->get('facebook', 'appSecret'));
        if (self::$initialized) {
            return;
        }
        //some custom logic
        if ((User::isLoggedIn()) && (User::current()->hasFacebookAccount())) {
            try {
                self::$session = new FacebookSession(User::current()->getFacebookAccessToken());
                self::$isSessionValid = self::$session->validate();
                if (self::$isSessionValid) {
                    if (!self::$session->getAccessToken()->isLongLived()) {
                        self::$session = self::$session->getLongLivedSession();
                    }
                    if (User::current()->getFacebookAccessToken() !== self::$session->getToken()) {
                        User::current()->setFacebookAccessToken(self::$session->getToken())->store();
                    }
                }
            } catch (\Facebook\FacebookSDKException $exception) {
                User::current()->disableFacebook();
                self::init();
            }
        } else {
            $helper = new \Facebook\FacebookRedirectLoginHelper(\BaseClass::$mainSiteName);
            self::$session = $helper->getSessionFromRedirect();            
            if (!!self::$session) {
                $request = new \Facebook\FacebookRequest( self::$session, 'GET', '/me' );
                $response = $request->execute();
                // get response
                $graphObject = $response->getGraphObject()->asArray();
                $user = \User::isLoggedIn() ? \User::current() : \User::getUserByFacebookID($graphObject["id"]);
                if (!self::$session->getAccessToken()->isLongLived()) {
                    self::$session = self::$session->getLongLivedSession();
                }
                $myToken = self::$session->getToken();
                if (!!$user) {
                    if (($user->getFacebookAccessToken() !== $myToken) || ($user->getFacebookId() !== $graphObject["id"])) {
                        $user->setFacebookAccessToken($myToken)->setFacebookId($graphObject["id"])->store();
                    }
                    if (!User::isLoggedIn()) {
                        $user->loginWithoutAuthentification();
                    }
                } else {
                    //create user
                }
            }
        }
        //login
        self::createFacebookActionPrivilege(self::$ACTION_LOGIN_KEY, self::$PRIVILEGE_PUBLIC_PROFILE_KEY, true);
        self::createFacebookActionPrivilege(self::$ACTION_LOGIN_KEY, self::$PRIVILEGE_EMAIL_KEY, false);

        //post
        self::createFacebookActionPrivilege(self::$ACTION_POST_KEY, self::$PRIVILEGE_PUBLISH_ACTIONS_KEY, true);

        //find friends
        self::createFacebookActionPrivilege(self::$ACTION_FIND_FRIENDS_KEY, self::$PRIVILEGE_FIND_FRIENDS_KEY, true);

        self::$initialized = true;
    }

    public static function getUsefulPrivileges($actionKey, $mandatory = false) {
        $privileges = array();
        foreach (self::$facebookActionPrivileges as $currentActionKey => $facebookActionPrivilege) {
            if ($currentActionKey === $actionKey) {
                foreach ($facebookActionPrivilege as $currentPrivilegeKey => $privilege) {
                    if ((!$mandatory) || ($privilege)) {
                        $privileges[] = array("key" => $currentPrivilegeKey, "mandatory" => $privilege);
                    } 
                }
            }
        }
        return $privileges;
    }

    public static function getPrivilegedURL($actionKey, $toLogin = false) {
        FacebookActionPrivilege::init();
        $distantPrivileges = FacebookActionPrivilege::getDistantPrivileges(); //Line 147
        if ((!is_array($distantPrivileges)) && (!is_object($distantPrivileges))) {
            $distantPrivileges = array();
        }
        $privilegeDataElements = array();
        $privileges = FacebookActionPrivilege::getUsefulPrivileges($actionKey);
        if ($toLogin) {
            $privileges = array_merge($privileges, FacebookActionPrivilege::getUsefulPrivileges(self::$ACTION_LOGIN_KEY));
        }
        foreach ($privileges as $privilege) {
            $found = false;
            foreach ($distantPrivileges as $distantPrivilege) {
                if ((!$found) && ($privilege["key"] === $distantPrivilege->permission)) {
                    $found = true;
                    $privilegeDataElements[$privilege["key"]] = array("mandatory" => $privilege["mandatory"], "granted" => ((isset($distantPrivilege->status)) && ($distantPrivilege->status === "granted")));
                }
            }
            if (!$found) {
                $privilegeDataElements[$privilege["key"]] = array("mandatory" => $privilege["mandatory"], "granted" => false);
            }
        }

        $privilegesToBeAsked = array();
        foreach ($privilegeDataElements as $key => $privilegeDataElement) {
            if ((!isset($privilegeDataElement["granted"])) || (!$privilegeDataElement["granted"])) {
                $privilegesToBeAsked[] = $key;
            }
        }
        $isPossible = true;

        foreach ($privilegesToBeAsked as $privilegeToBeAsked) {
            $isPossible = $isPossible && $privilegeDataElements[$privilegeToBeAsked]["granted"];
        }
        $url = "";
        if (count($privilegesToBeAsked) > 0) {
            $helper = new \Facebook\FacebookRedirectLoginHelper(\BaseClass::$mainSiteName);
            $url .= $helper->getLoginUrl($privilegesToBeAsked);
        }

        return array("possible" => $isPossible, "url" => $url);
    }

    private static function createFacebookActionPrivilege($actionKey, $privilegeKey, $mandatory) {
        if (!isset(self::$facebookActionPrivileges[$actionKey])) {
            self::$facebookActionPrivileges[$actionKey] = array();
        }
        self::$facebookActionPrivileges[$actionKey][$privilegeKey] = $mandatory;
    }

}

拥有 Facebook 帐户的用户试图在应用程序中查找他或她的 Facebook 好友,这触发了以下代码:

if(User::current()->hasFacebookAccount()){
    $permissions = Facebook\FacebookAccessor\FacebookActionPrivilege::getPrivilegedURL(Facebook\FacebookAccessor\FacebookActionPrivilege::$ACTION_FIND_FRIENDS_KEY);
    //...
}

但是,初始化 $permissions 时抛出了以下异常:

Exception 'Facebook\FacebookAuthorizationException' with message '(#412) User has not installed the application' in /www/myproject-prod/master/lib/Facebook/FacebookRequestException.php:134

#0 Facebook\FacebookRequestException::create("{"error":{"message":"(#412) User has not installed",object,integer(400))/www/myproject-prod/master/lib/Facebook/FacebookRequest.php:268
#1 Facebook\FacebookRequest::execute()/www/myproject-prod/master/lib/Facebook/FacebookAccessor/FacebookActionPrivilege.php:44
#2 Facebook\FacebookAccessor\FacebookActionPrivilege::getDistantPrivileges()/www/myproject-prod/master/lib/Facebook/FacebookAccessor/FacebookActionPrivilege.php:147
#3 Facebook\FacebookAccessor\FacebookActionPrivilege::getPrivilegedURL("find_friends")/www/myproject-prod/master/mobile/view/account/find_people.php:142
#4 include_once("/www/myproject-prod/master/mobile/view/account/find_")/www/myproject-prod/master/mobile/user.php:33

例外是非常独特的,因为许多用户在使用该功能时没有任何问题,但是给定用户尝试查找 Facebook 朋友时产生了这个问题。由于这是 PHP Facebook SDK,我真的不明白应该安装什么应用程序。据我所知,用户必须允许 Facebook 应用程序并授予必要的权限。但是,异常消息指出未安装应用程序。我完全不知道为什么会抛出这个错误,因此我不知道如何重现它。关于可能是什么问题的任何想法?谢谢。

4

1 回答 1

1

我/朋友不再是用户朋友的简单列表,并且有更严格的检查以确保只有也在使用此应用程序的朋友出现。当我们说应用程序时,它可以是网络应用程序、使用 FB 登录的网页或移动应用程序。

一些有用的链接 - https://stackoverflow.com/a/23417628/4263244 https://developers.facebook.com/docs/apps/upgrading#upgrading_v2_0_user_ids

于 2015-09-08T08:17:29.847 回答