PageRenderTime 61ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/wordpress-social-login/hybridauth/Hybrid/Providers/Facebook.php

https://gitlab.com/dinhkk/muabanchungcu24
PHP | 386 lines | 249 code | 74 blank | 63 comment | 57 complexity | e0544af2fc7610fe0ac485d26d7b9a39 MD5 | raw file
  1. <?php
  2. /*!
  3. * HybridAuth
  4. * http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
  5. * (c) 2009-2012, HybridAuth authors | http://hybridauth.sourceforge.net/licenses.html
  6. */
  7. /**
  8. * Hybrid_Providers_Facebook provider adapter based on OAuth2 protocol
  9. *
  10. * Hybrid_Providers_Facebook use the Facebook PHP SDK created by Facebook
  11. *
  12. * http://hybridauth.sourceforge.net/userguide/IDProvider_info_Facebook.html
  13. */
  14. class Hybrid_Providers_Facebook extends Hybrid_Provider_Model
  15. {
  16. // default permissions, and a lot of them. You can change them from the configuration by setting the scope to what you want/need
  17. public $scope = "email, public_profile";
  18. /**
  19. * IDp wrappers initializer
  20. */
  21. function initialize()
  22. {
  23. if ( ! $this->config["keys"]["id"] || ! $this->config["keys"]["secret"] ){
  24. throw new Exception( "Your application id and secret are required in order to connect to {$this->providerId}.", 4 );
  25. }
  26. // Need to override package version
  27. if( class_exists('BaseFacebook', false ) && ! defined( 'GRAPH_API_VERSION' ) ){
  28. throw new Exception( "Confilict detected. Facebook SDK is already loaded by another package. Initialization failed, exit." );
  29. }
  30. require_once realpath( dirname( __FILE__ ) ) . "/../thirdparty/Facebook/base_facebook.php";
  31. require_once realpath( dirname( __FILE__ ) ) . "/../thirdparty/Facebook/facebook.php";
  32. if ( isset ( Hybrid_Auth::$config["proxy"] ) ) {
  33. BaseFacebook::$CURL_OPTS[CURLOPT_PROXY] = Hybrid_Auth::$config["proxy"];
  34. }
  35. $trustForwarded = isset( $this->config['trustForwarded'] ) ? (bool) $this->config['trustForwarded'] : false;
  36. $this->api = new Facebook( ARRAY( 'appId' => $this->config["keys"]["id"], 'secret' => $this->config["keys"]["secret"], 'trustForwarded' => $trustForwarded ) );
  37. }
  38. /**
  39. * begin login step
  40. *
  41. * simply call Facebook::require_login().
  42. */
  43. function loginBegin()
  44. {
  45. $parameters = array("scope" => $this->scope, "redirect_uri" => $this->endpoint, "display" => "page");
  46. $optionals = array("scope", "redirect_uri", "display", "auth_type");
  47. foreach ($optionals as $parameter){
  48. if( isset( $this->config[$parameter] ) && ! empty( $this->config[$parameter] ) ){
  49. $parameters[$parameter] = $this->config[$parameter];
  50. //If the auth_type parameter is used, we need to generate a nonce and include it as a parameter
  51. if($parameter == "auth_type"){
  52. $nonce = md5(uniqid(mt_rand(), true));
  53. $parameters['auth_nonce'] = $nonce;
  54. Hybrid_Auth::storage()->set('fb_auth_nonce', $nonce);
  55. }
  56. }
  57. }
  58. if( isset( $this->config[ 'force' ] ) && $this->config[ 'force' ] === true ){
  59. $parameters[ 'auth_type' ] = 'reauthenticate';
  60. $parameters[ 'auth_nonce' ] = md5( uniqid( mt_rand(), true ) );
  61. Hybrid_Auth::storage()->set( 'fb_auth_nonce', $parameters[ 'auth_nonce' ] );
  62. }
  63. // get the login url
  64. $url = $this->api->getLoginUrl( $parameters );
  65. // redirect to facebook
  66. Hybrid_Auth::redirect( $url );
  67. }
  68. /**
  69. * finish login step
  70. */
  71. function loginFinish()
  72. {
  73. // in case we get error_reason=user_denied&error=access_denied
  74. if ( isset( $_REQUEST['error'] ) && $_REQUEST['error'] == "access_denied" ){
  75. throw new Exception( "Authentication failed! The user denied your request.", 5 );
  76. }
  77. // in case we are using iOS/Facebook reverse authentication
  78. if(isset($_REQUEST['access_token'])){
  79. $this->token("access_token", $_REQUEST['access_token'] );
  80. $this->api->setAccessToken( $this->token("access_token") );
  81. $this->api->setExtendedAccessToken();
  82. $access_token = $this->api->getAccessToken();
  83. if( $access_token ){
  84. $this->token("access_token", $access_token );
  85. $this->api->setAccessToken( $access_token );
  86. }
  87. $this->api->setAccessToken( $this->token("access_token") );
  88. }
  89. // if auth_type is used, then an auth_nonce is passed back, and we need to check it.
  90. if(isset($_REQUEST['auth_nonce'])){
  91. $nonce = Hybrid_Auth::storage()->get('fb_auth_nonce');
  92. //Delete the nonce
  93. Hybrid_Auth::storage()->delete('fb_auth_nonce');
  94. if($_REQUEST['auth_nonce'] != $nonce){
  95. throw new Exception( "Authentication failed! Invalid nonce used for reauthentication.", 5 );
  96. }
  97. }
  98. // try to get the UID of the connected user from fb, should be > 0
  99. if ( ! $this->api->getUser() ){
  100. throw new Exception( "Authentication failed! {$this->providerId} returned an invalid user id.", 5 );
  101. }
  102. // set user as logged in
  103. $this->setUserConnected();
  104. // store facebook access token
  105. $this->token( "access_token", $this->api->getAccessToken() );
  106. }
  107. /**
  108. * logout
  109. */
  110. function logout()
  111. {
  112. $this->api->destroySession();
  113. parent::logout();
  114. }
  115. /**
  116. * setAccessToken
  117. */
  118. function setAccessToken()
  119. {
  120. if ( $this->token("access_token") ) {
  121. $this->api->setAccessToken( $this->token("access_token") );
  122. $this->api->setExtendedAccessToken();
  123. $access_token = $this->api->getAccessToken();
  124. if( $access_token ){
  125. $this->token("access_token", $access_token );
  126. $this->api->setAccessToken( $access_token );
  127. }
  128. $this->api->setAccessToken( $this->token("access_token") );
  129. }
  130. }
  131. /**
  132. * load the user profile from the IDp api client
  133. */
  134. function getUserProfile()
  135. {
  136. // request user profile from fb api
  137. try{
  138. $this->setAccessToken();
  139. $fields = array(
  140. 'id', 'name', 'first_name', 'last_name', 'link', 'website',
  141. 'gender', 'locale', 'about', 'email', 'hometown', 'location',
  142. 'verified'
  143. );
  144. $data = $this->api->api('/me?fields=' . implode(',', $fields));
  145. }
  146. catch( FacebookApiException $e ){
  147. throw new Exception( "User profile request failed! {$this->providerId} returned an error", 6 );
  148. }
  149. // if the provider identifier is not received, we assume the auth has failed
  150. if ( ! isset( $data["id"] ) ){
  151. throw new Exception( "User profile request failed! {$this->providerId} api returned an invalid response.", 6 );
  152. }
  153. # store the user profile.
  154. $this->user->profile->identifier = (array_key_exists('id',$data))?$data['id']:"";
  155. $this->user->profile->username = (array_key_exists('username',$data))?$data['username']:"";
  156. $this->user->profile->displayName = (array_key_exists('name',$data))?$data['name']:"";
  157. $this->user->profile->firstName = (array_key_exists('first_name',$data))?$data['first_name']:"";
  158. $this->user->profile->lastName = (array_key_exists('last_name',$data))?$data['last_name']:"";
  159. $this->user->profile->photoURL = "https://graph.facebook.com/" . $this->user->profile->identifier . "/picture?width=150&height=150";
  160. $this->user->profile->profileURL = (array_key_exists('link',$data))?$data['link']:"";
  161. $this->user->profile->webSiteURL = (array_key_exists('website',$data))?$data['website']:"";
  162. $this->user->profile->gender = (array_key_exists('gender',$data))?$data['gender']:"";
  163. $this->user->profile->language = (array_key_exists('locale',$data))?$data['locale']:"";
  164. $this->user->profile->description = (array_key_exists('about',$data))?$data['about']:"";
  165. $this->user->profile->email = (array_key_exists('email',$data))?$data['email']:"";
  166. $this->user->profile->region = (array_key_exists("hometown",$data)&&array_key_exists("name",$data['hometown']))?$data['hometown']["name"]:"";
  167. if( array_key_exists('verified',$data ) && $data['verified'] == 1 ){
  168. $this->user->profile->emailVerified = $this->user->profile->email;
  169. }
  170. if(!empty($this->user->profile->region )){
  171. $regionArr = explode(',',$this->user->profile->region );
  172. if(count($regionArr) > 1){
  173. $this->user->profile->city = trim($regionArr[0]);
  174. $this->user->profile->country = trim($regionArr[1]);
  175. }
  176. }
  177. if( array_key_exists('birthday',$data) ) {
  178. list($birthday_month, $birthday_day, $birthday_year) = explode( "/", $data['birthday'] );
  179. $this->user->profile->birthDay = (int) $birthday_day;
  180. $this->user->profile->birthMonth = (int) $birthday_month;
  181. $this->user->profile->birthYear = (int) $birthday_year;
  182. }
  183. return $this->user->profile;
  184. }
  185. /**
  186. * load the user contacts
  187. */
  188. function getUserContacts()
  189. {
  190. $apiCall = '?fields=link,name';
  191. $returnedContacts = array();
  192. $pagedList = false;
  193. do {
  194. try{
  195. $this->setAccessToken();
  196. $response = $this->api->api('/me/friends' . $apiCall);
  197. }
  198. catch( FacebookApiException $e ){
  199. throw new Exception( 'User contacts request failed! {$this->providerId} returned an error' );
  200. }
  201. // Prepare the next call if paging links have been returned
  202. if (array_key_exists('paging', $response) && array_key_exists('next', $response['paging'])) {
  203. $pagedList = true;
  204. $next_page = explode('friends', $response['paging']['next']);
  205. $apiCall = $next_page[1];
  206. }
  207. else{
  208. $pagedList = false;
  209. }
  210. // Add the new page contacts
  211. $returnedContacts = array_merge($returnedContacts, $response['data']);
  212. }
  213. while ($pagedList == true);
  214. $contacts = ARRAY();
  215. foreach( $returnedContacts as $item ){
  216. $uc = new Hybrid_User_Contact();
  217. $uc->identifier = (array_key_exists("id",$item))?$item["id"]:"";
  218. $uc->displayName = (array_key_exists("name",$item))?$item["name"]:"";
  219. $uc->profileURL = (array_key_exists("link",$item))?$item["link"]:"https://www.facebook.com/profile.php?id=" . $uc->identifier;
  220. $uc->photoURL = "https://graph.facebook.com/" . $uc->identifier . "/picture?width=150&height=150";
  221. $contacts[] = $uc;
  222. }
  223. return $contacts;
  224. }
  225. /**
  226. * update user status
  227. *
  228. * @param string $pageid (optional) User page id
  229. */
  230. function setUserStatus( $status, $pageid = null )
  231. {
  232. if( !is_array( $status ) ){
  233. $status = array( 'message' => $status );
  234. }
  235. if( is_null( $pageid ) ){
  236. $pageid = 'me';
  237. // if post on page, get access_token page
  238. }else{
  239. $access_token = null;
  240. foreach( $this->getUserPages( true ) as $p ){
  241. if( isset( $p[ 'id' ] ) && intval( $p['id'] ) == intval( $pageid ) ){
  242. $access_token = $p[ 'access_token' ];
  243. break;
  244. }
  245. }
  246. if( is_null( $access_token ) ){
  247. throw new Exception( "Update user page failed, page not found or not writeable!" );
  248. }
  249. $status[ 'access_token' ] = $access_token;
  250. }
  251. try{
  252. $this->setAccessToken();
  253. $response = $this->api->api( '/' . $pageid . '/feed', 'post', $status );
  254. }
  255. catch( FacebookApiException $e ){
  256. throw new Exception( "Update user status failed! {$this->providerId} returned an error: $e" );
  257. }
  258. return $response;
  259. }
  260. /**
  261. * load the user latest activity
  262. * - timeline : all the stream
  263. * - me : the user activity only
  264. */
  265. function getUserActivity( $stream )
  266. {
  267. try{
  268. $this->setAccessToken();
  269. if( $stream == "me" ){
  270. $response = $this->api->api( '/me/feed' );
  271. }
  272. else{
  273. $response = $this->api->api('/me/home');
  274. }
  275. }
  276. catch( FacebookApiException $e ){
  277. throw new Exception( "User activity stream request failed! {$this->providerId} returned an error: $e" );
  278. }
  279. if( ! $response || ! count( $response['data'] ) ){
  280. return ARRAY();
  281. }
  282. $activities = ARRAY();
  283. foreach( $response['data'] as $item ){
  284. if( $stream == "me" && $item["from"]["id"] != $this->api->getUser() ){
  285. continue;
  286. }
  287. $ua = new Hybrid_User_Activity();
  288. $ua->id = (array_key_exists("id",$item))?$item["id"]:"";
  289. $ua->date = (array_key_exists("created_time",$item))?strtotime($item["created_time"]):"";
  290. if( $item["type"] == "video" ){
  291. $ua->text = (array_key_exists("link",$item))?$item["link"]:"";
  292. }
  293. if( $item["type"] == "link" ){
  294. $ua->text = (array_key_exists("link",$item))?$item["link"]:"";
  295. }
  296. if( empty( $ua->text ) && isset( $item["story"] ) ){
  297. $ua->text = (array_key_exists("link",$item))?$item["link"]:"";
  298. }
  299. if( empty( $ua->text ) && isset( $item["message"] ) ){
  300. $ua->text = (array_key_exists("message",$item))?$item["message"]:"";
  301. }
  302. if( ! empty( $ua->text ) ){
  303. $ua->user->identifier = (array_key_exists("id",$item["from"]))?$item["from"]["id"]:"";
  304. $ua->user->displayName = (array_key_exists("name",$item["from"]))?$item["from"]["name"]:"";
  305. $ua->user->profileURL = "https://www.facebook.com/profile.php?id=" . $ua->user->identifier;
  306. $ua->user->photoURL = "https://graph.facebook.com/" . $ua->user->identifier . "/picture?type=square";
  307. $activities[] = $ua;
  308. }
  309. }
  310. return $activities;
  311. }
  312. }