我正在使用Facebook SDK for PHP。几个月前,当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应用程序并授予必要的权限。但是,异常消息指出未安装应用程序。我完全不知道为什么会抛出这个错误,因此我不知道如何重现它。关于什么可能是问题的任何想法?感谢。