1
|
|
|
<?php |
|
|
|
|
2
|
|
|
/** |
3
|
|
|
* A controller that connects with Facebook, using the Facebook PHP SDK |
4
|
|
|
* |
5
|
|
|
* USEFUL LINKS: |
6
|
|
|
* https://developers.facebook.com/docs/reference/login/extended-permissions/ |
7
|
|
|
* |
8
|
|
|
*/ |
9
|
|
|
|
10
|
|
|
if (!defined("SS_FACEBOOK_API_PATH")) { |
11
|
|
|
define("SS_FACEBOOK_API_PATH", str_replace("/code/control", "", dirname(__FILE__))."/thirdparty/facebook/src/"); |
12
|
|
|
} |
13
|
|
|
require_once SS_FACEBOOK_API_PATH . 'facebook.php'; |
14
|
|
|
|
15
|
|
|
class FacebookCallback extends SocialIntegrationControllerBaseClass implements SocialIntegrationAPIInterface |
|
|
|
|
16
|
|
|
{ |
17
|
|
|
|
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* Maximum number of friends that can be retrieved |
21
|
|
|
* @var Int |
22
|
|
|
*/ |
23
|
|
|
private static $number_of_friends_that_can_be_retrieved = 1200; |
24
|
|
|
public static function set_number_of_friends_that_can_be_retrieved($n) |
25
|
|
|
{ |
26
|
|
|
self::$number_of_friends_that_can_be_retrieved = $s; |
|
|
|
|
27
|
|
|
} |
28
|
|
|
public static function get_number_of_friends_that_can_be_retrieved() |
29
|
|
|
{ |
30
|
|
|
return self::$number_of_friends_that_can_be_retrieved; |
31
|
|
|
} |
32
|
|
|
|
33
|
|
|
//======================================= AVAILABLE METHODS =============================================== |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* Standard SS variable |
37
|
|
|
* @var Array |
38
|
|
|
*/ |
39
|
|
|
public static $allowed_actions = array( |
40
|
|
|
'FacebookConnect', |
41
|
|
|
'Connect', |
42
|
|
|
'Login', |
43
|
|
|
'FinishFacebook', |
44
|
|
|
'remove', |
45
|
|
|
'test' |
46
|
|
|
); |
47
|
|
|
|
48
|
|
|
|
49
|
|
|
//======================================= CONFIGURATION STATIC =============================================== |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* get it from developer.facebook.com |
53
|
|
|
* @var String |
54
|
|
|
*/ |
55
|
|
|
protected static $facebook_id = null; |
56
|
|
|
public static function set_facebook_id($i) |
57
|
|
|
{ |
58
|
|
|
self::$facebook_id = $i; |
59
|
|
|
} |
60
|
|
|
public static function get_facebook_id() |
61
|
|
|
{ |
62
|
|
|
return self::$facebook_id; |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
/** |
66
|
|
|
* get it from developer.facebook.com |
67
|
|
|
* @var String |
68
|
|
|
*/ |
69
|
|
|
protected static $facebook_secret = null; |
70
|
|
|
public static function set_facebook_secret($s) |
71
|
|
|
{ |
72
|
|
|
self::$facebook_secret = $s; |
73
|
|
|
} |
74
|
|
|
public static function get_facebook_secret() |
75
|
|
|
{ |
76
|
|
|
return self::$facebook_secret; |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
/** |
80
|
|
|
* use email as a back-up |
81
|
|
|
* for checking if the user already exists. |
82
|
|
|
* @var Boolean |
83
|
|
|
*/ |
84
|
|
|
protected static $email_fallback = true; |
85
|
|
|
public static function get_email_fallback() |
86
|
|
|
{ |
87
|
|
|
return self::$email_fallback; |
88
|
|
|
} |
89
|
|
|
public static function set_email_fallback($val) |
90
|
|
|
{ |
91
|
|
|
self::$email_fallback = (bool)$val; |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* @see: https://developers.facebook.com/docs/authentication/permissions/ |
97
|
|
|
* @var Array |
98
|
|
|
*/ |
99
|
|
|
protected static $permissions = false; |
100
|
|
|
public static function add_permission($s) |
101
|
|
|
{ |
102
|
|
|
if (!self::$permissions) { |
|
|
|
|
103
|
|
|
self::$permissions = array(); |
104
|
|
|
} if (!in_array($s, self::$permissions)) { |
105
|
|
|
self::$permissions[] = $s; |
106
|
|
|
} |
107
|
|
|
} |
108
|
|
|
public static function set_permissions($a) |
109
|
|
|
{ |
110
|
|
|
self::$permissions = $a; |
111
|
|
|
} |
112
|
|
|
public static function get_permissions() |
113
|
|
|
{ |
114
|
|
|
return self::$permissions; |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
|
118
|
|
|
//======================================= CONFIGURATION NON-STATIC =============================================== |
119
|
|
|
|
120
|
|
|
|
121
|
|
|
|
122
|
|
|
|
123
|
|
|
//======================================= THIRD-PARTY CONNECTION =============================================== |
124
|
|
|
|
125
|
|
|
/** |
126
|
|
|
* |
127
|
|
|
* |
128
|
|
|
* @var facebook Class |
129
|
|
|
*/ |
130
|
|
|
protected static $facebook_sdk_class = null; |
131
|
|
|
|
132
|
|
|
/** |
133
|
|
|
* holds an instance of the FB class |
134
|
|
|
* @param Boolean $getEvenWithoutCurrentMember |
135
|
|
|
* @return Facebook |
136
|
|
|
*/ |
137
|
|
|
protected static function get_facebook_sdk_class($getEvenWithoutCurrentMember = false) |
138
|
|
|
{ |
139
|
|
|
if (!self::$facebook_id || !self::$facebook_secret) { |
140
|
|
|
user_error("You must set the following variables: Facebook::facebook_id AND Facebook::facebook_secret"); |
141
|
|
|
} |
142
|
|
|
if (!self::$facebook_sdk_class) { |
143
|
|
|
$member = Member::currentUser(); |
144
|
|
|
if (($member && $member->FacebookID) || $getEvenWithoutCurrentMember) { |
145
|
|
|
self::$facebook_sdk_class = new Facebook( |
146
|
|
|
array( |
147
|
|
|
'appId' => self::$facebook_id, |
148
|
|
|
'secret' => self::$facebook_secret, |
149
|
|
|
'cookie' => true |
150
|
|
|
) |
151
|
|
|
); |
152
|
|
|
} |
153
|
|
|
} |
154
|
|
|
return self::$facebook_sdk_class; |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
|
158
|
|
|
//======================================= STATIC METHODS =============================================== |
159
|
|
|
|
160
|
|
|
/** |
161
|
|
|
* returns the currently logged in FB user |
162
|
|
|
* @return Object | Null |
163
|
|
|
*/ |
164
|
|
|
public static function get_current_user() |
165
|
|
|
{ |
166
|
|
|
$user = null; |
167
|
|
|
$data = null; |
168
|
|
|
$facebook = self::get_facebook_sdk_class(); |
169
|
|
|
if ($facebook) { |
170
|
|
|
$user = $facebook->getUser(); |
171
|
|
|
if ($user) { |
172
|
|
|
try { |
173
|
|
|
$data = $facebook->api('/me'); |
174
|
|
|
if (isset($data->error)) { |
175
|
|
|
$data = null; |
176
|
|
|
SS_Log::log($data->error->message, SS_Log::NOTICE); |
177
|
|
|
} |
178
|
|
|
} catch (FacebookApiException $e) { |
|
|
|
|
179
|
|
|
$data = null; |
180
|
|
|
SS_Log::log($e, SS_Log::NOTICE); |
181
|
|
|
} |
182
|
|
|
try { |
183
|
|
|
$picture = $facebook->api('/me/?fields=picture'); |
184
|
|
|
if (isset($picture["picture"]["data"]["url"])) { |
185
|
|
|
$data["picture"] = $picture["picture"]["data"]["url"]; |
186
|
|
|
} |
187
|
|
|
if (isset($data->error)) { |
188
|
|
|
SS_Log::log(print_r($data->error, 1).$data->error->message, SS_Log::NOTICE); |
189
|
|
|
} |
190
|
|
|
} catch (FacebookApiException $e) { |
|
|
|
|
191
|
|
|
SS_Log::log($e, SS_Log::NOTICE); |
192
|
|
|
} |
193
|
|
|
} |
194
|
|
|
} |
195
|
|
|
return $user ? $data : null; |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
/* |
199
|
|
|
/** |
200
|
|
|
* returns true if the message is sent successfully |
201
|
|
|
* @param Int | Member | String $to |
202
|
|
|
* @param String $message |
203
|
|
|
* @param String $link - link to send with message |
204
|
|
|
* @param Array $otherVariables - other variables used in message. |
205
|
|
|
- $redirect_uri = "", |
206
|
|
|
- $RedirectURL = "", |
207
|
|
|
- $name = "", |
208
|
|
|
- $caption = "", |
209
|
|
|
- $description = "", |
210
|
|
|
- $pictureURL = "", |
211
|
|
|
- $Subject = "", |
212
|
|
|
- $actions = array() |
213
|
|
|
* @param String $senderEmail - link to send with message |
|
|
|
|
214
|
|
|
|
215
|
|
|
* @see: https://developers.facebook.com/docs/reference/php/facebook-api/ |
216
|
|
|
* @see http://facebook.stackoverflow.com/questions/2943297/how-send-message-facebook-friend-through-graph-api-using-accessstoken |
217
|
|
|
* |
218
|
|
|
* @return EmailLink (Dialogue Feed) |
|
|
|
|
219
|
|
|
*/ |
220
|
|
|
public static function send_message( |
221
|
|
|
$to = "me", |
222
|
|
|
$message, |
|
|
|
|
223
|
|
|
$link = "", |
224
|
|
|
$otherVariables = array() |
225
|
|
|
) { |
226
|
|
|
//FACEBOOK |
227
|
|
|
if ($to instanceof Member) { |
228
|
|
|
$to = $to->FacebookUsername; |
229
|
|
|
} |
230
|
|
|
$facebook = self::get_facebook_sdk_class(); |
231
|
|
|
if ($facebook) { |
232
|
|
|
$user = $facebook->getUser(); |
233
|
|
|
//get email data that does not go to GRAPH: |
234
|
|
|
if (isset($otherVariables["senderEmail"])) { |
235
|
|
|
$senderEmail = $otherVariables["senderEmail"]; |
236
|
|
|
unset($otherVariables["senderEmail"]); |
237
|
|
|
} elseif ($sender = Member::currentUser()) { |
238
|
|
|
$senderEmail = $sender->Email; |
239
|
|
|
} |
240
|
|
|
|
241
|
|
|
//start hack |
242
|
|
|
$message = trim(strip_tags(stripslashes($message))); |
243
|
|
|
//end hack |
244
|
|
|
$postArray = array( |
245
|
|
|
'message' => $message, |
246
|
|
|
'link' => $link, |
247
|
|
|
); |
248
|
|
|
if (count($otherVariables)) { |
249
|
|
|
foreach ($otherVariables as $key => $value) { |
250
|
|
|
$postArray[$key] = $value; |
251
|
|
|
} |
252
|
|
|
} |
253
|
|
|
if ($user) { |
254
|
|
View Code Duplication |
if (empty($otherVariables["Subject"])) { |
|
|
|
|
255
|
|
|
$subject = substr($message, 0, 30); |
256
|
|
|
} else { |
257
|
|
|
$subject = $otherVariables["Subject"]; |
258
|
|
|
} |
259
|
|
|
//------------- SEND EMAIL TO START DIALOGUE --- |
260
|
|
|
//BUILD LINK |
261
|
|
|
$emailLink = "https://www.facebook.com/dialog/feed?" |
262
|
|
|
."to=".$to."&" |
263
|
|
|
."app_id=".self::get_facebook_id()."&" |
264
|
|
|
."link=".urlencode($link)."&" |
265
|
|
|
."message=".urlencode($message)."&"; |
266
|
|
|
//FROM |
267
|
|
|
if (isset($otherVariables["redirect_uri"])) { |
268
|
|
|
$emailLink .= "redirect_uri=".urlencode(Director::absoluteURL("/").$otherVariables["redirect_uri"])."&"; |
269
|
|
View Code Duplication |
} elseif (isset($otherVariables["RedirectURL"])) { |
|
|
|
|
270
|
|
|
$emailLink .= "redirect_uri=".urlencode(Director::absoluteURL("/").$otherVariables["RedirectURL"])."&"; |
271
|
|
|
} else { |
272
|
|
|
$emailLink .= "redirect_uri=".urlencode(Director::absoluteURL("/"))."&"; |
273
|
|
|
} |
274
|
|
View Code Duplication |
if (isset($otherVariables["pictureURL"])) { |
|
|
|
|
275
|
|
|
$emailLink .= "picture=".urlencode(Director::absoluteURL("/").$otherVariables["pictureURL"])."&"; |
276
|
|
|
} |
277
|
|
View Code Duplication |
if (isset($otherVariables["description"])) { |
|
|
|
|
278
|
|
|
$emailLink .= "description=".urlencode($otherVariables["description"])."&"; |
279
|
|
|
} elseif ($message) { |
280
|
|
|
$emailLink .= "description=".urlencode($message)."&"; |
281
|
|
|
} |
282
|
|
|
if (isset($otherVariables["name"])) { |
283
|
|
|
$emailLink .= "name=".urlencode($otherVariables["name"])."&"; |
284
|
|
|
} |
285
|
|
View Code Duplication |
if (isset($otherVariables["caption"])) { |
|
|
|
|
286
|
|
|
$emailLink .= "caption=".urlencode($otherVariables["caption"])."&"; |
287
|
|
|
} elseif (isset($otherVariables["Subject"])) { |
288
|
|
|
$emailLink .= "caption=".urlencode($otherVariables["Subject"])."&"; |
289
|
|
|
} |
290
|
|
|
$from = Email::getAdminEmail(); |
291
|
|
|
//TO |
292
|
|
|
//SUBJECT |
293
|
|
|
$subject = _t("FacebookCallback.ACTION_REQUIRED", "Action required for").": ".$subject; |
294
|
|
|
//BODY |
295
|
|
|
$body = |
296
|
|
|
_t("FacebookCallback.PLEASE_CLICK_ON_THE_LINK", " Please click on the link ") |
297
|
|
|
." <a href=\"".$emailLink."\" target=\"_blank\">"._t("FacebookCallback.OPEN_FACEBOOK", "open facebook")."</a> ". |
298
|
|
|
_t("FacebookCallback.TO_SEND_A_MESSAGE_TO_FRIEND", "to send a message to your friend. "). |
299
|
|
|
_t("FacebookCallback.DIRECT_LINK", " You can also send the link directly to your friend: ").$link; |
300
|
|
|
//BCC |
301
|
|
|
$bcc = Email::getAdminEmail(); |
|
|
|
|
302
|
|
|
//SEND |
303
|
|
|
$email = new Email( |
304
|
|
|
$from, |
305
|
|
|
$senderEmail, |
|
|
|
|
306
|
|
|
$subject, |
307
|
|
|
$body |
308
|
|
|
); |
309
|
|
|
$email->send(); |
310
|
|
|
// We have a user ID, so probably a logged in user. |
311
|
|
|
// If not, we'll get an exception, which we handle below. |
312
|
|
|
if (1 == 2) { |
313
|
|
|
if ($to instanceof Member) { |
314
|
|
|
$to = $to->FacebookUsername; |
315
|
|
|
} |
316
|
|
|
try { |
317
|
|
|
$ret_obj = $facebook->api('/'.$to.'/feed', 'POST', $postArray); |
|
|
|
|
318
|
|
|
//SS_Log::log($ret_obj, SS_Log::NOTICE); |
|
|
|
|
319
|
|
|
return $body; |
320
|
|
|
} catch (FacebookApiException $e) { |
|
|
|
|
321
|
|
|
// If the user is logged out, you can have a |
322
|
|
|
// user ID even though the access token is invalid. |
323
|
|
|
// In this case, we'll get an exception, so we'll |
324
|
|
|
// just ask the user to login again here. |
325
|
|
|
SS_Log::log($user."---".$e->getType()."---".$e->getMessage()."---".$to."---".$message."---".$link."---".$otherVariables."---".print_r($user, 1).print_r(Member::currentUser(), 1), SS_Log::NOTICE); |
326
|
|
|
} |
327
|
|
|
} |
328
|
|
|
} else { |
329
|
|
|
SS_Log::log("tried to send a message from facebook without being logging in...", SS_Log::NOTICE); |
330
|
|
|
} |
331
|
|
|
} |
332
|
|
|
return false; |
333
|
|
|
} |
334
|
|
|
|
335
|
|
|
|
336
|
|
|
/** |
337
|
|
|
* gets a list of friends |
338
|
|
|
* @param Int - $Limit, set to -1 to to maximum |
339
|
|
|
* @param String - $searchString, filter for search string |
340
|
|
|
* @return Array (array("id" => ..., "name" => ...., "picture" => ...)) |
341
|
|
|
*/ |
342
|
|
|
public static function get_list_of_friends($limit = 12, $searchString = "") |
343
|
|
|
{ |
344
|
|
|
if ($limit == -1) { |
345
|
|
|
$limit = self::get_number_of_friends_that_can_be_retrieved(); |
346
|
|
|
} |
347
|
|
|
$returnObject = array(); |
348
|
|
|
$facebook = self::get_facebook_sdk_class(); |
349
|
|
|
if ($facebook) { |
350
|
|
|
if ($user = $facebook->getUser()) { |
|
|
|
|
351
|
|
|
$fullList = $facebook->api('/me/friends?fields=id,name,picture'); |
352
|
|
|
$count = 0; |
353
|
|
|
if (Director::isDev()) { |
354
|
|
|
$me = self::get_current_user(); |
355
|
|
|
$returnObject[$count]["id"] = $me["id"]; |
356
|
|
|
$returnObject[$count]["name"] = $me["name"]; |
357
|
|
|
$returnObject[$count]["picture"] = $me["picture"]; |
358
|
|
|
$count++; |
359
|
|
|
} |
360
|
|
|
if (isset($fullList["data"])) { |
361
|
|
|
$limitCount = 0; |
|
|
|
|
362
|
|
|
foreach ($fullList["data"] as $friend) { |
363
|
|
|
if (!$searchString || stripos("-".$friend["name"], $searchString)) { |
364
|
|
|
$returnObject[$count]["id"] = $friend["id"]; |
365
|
|
|
$returnObject[$count]["name"] = $friend["name"]; |
366
|
|
|
if (isset($friend["picture"]["data"]["url"])) { |
367
|
|
|
$returnObject[$count]["picture"] = $friend["picture"]["data"]["url"]; |
368
|
|
|
} elseif (isset($friend["picture"])) { |
369
|
|
|
$returnObject[$count]["picture"] = $friend["picture"]; |
370
|
|
|
} |
371
|
|
|
$count++; |
372
|
|
|
} |
373
|
|
|
if ($count >= $limit) { |
374
|
|
|
break; |
375
|
|
|
} |
376
|
|
|
} |
377
|
|
|
} |
378
|
|
|
} |
379
|
|
|
} |
380
|
|
|
return $returnObject; |
381
|
|
|
} |
382
|
|
|
|
383
|
|
|
public static function is_valid_user($id) |
384
|
|
|
{ |
385
|
|
|
return true; |
386
|
|
|
} |
387
|
|
|
|
388
|
|
|
public static function get_updates($lastNumber = 12) |
389
|
|
|
{ |
390
|
|
|
$returnObject = array(); |
|
|
|
|
391
|
|
|
$facebook = self::get_facebook_sdk_class(); |
392
|
|
|
if ($facebook) { |
393
|
|
|
if ($user = $facebook->getUser()) { |
|
|
|
|
394
|
|
|
return $facebook->api( |
395
|
|
|
$path = "/me/statuses", |
396
|
|
|
$method = "GET", |
397
|
|
|
$params = array( |
398
|
|
|
"limit" => 100, |
399
|
|
|
"since" => 2005, |
400
|
|
|
) |
401
|
|
|
); |
402
|
|
|
} |
403
|
|
|
} |
404
|
|
|
} |
405
|
|
|
//======================================= STANDARD SS METHODS =============================================== |
406
|
|
|
|
407
|
|
|
/** |
408
|
|
|
* magical PHP method |
409
|
|
|
*/ |
410
|
|
|
public function __construct() |
411
|
|
|
{ |
412
|
|
|
if (self::$facebook_secret == null || self::$facebook_id == null) { |
413
|
|
|
user_error('Cannot instigate a FacebookCallback object without an application secret and id', E_USER_ERROR); |
414
|
|
|
} |
415
|
|
|
parent::__construct(); |
416
|
|
|
} |
417
|
|
|
|
418
|
|
|
|
419
|
|
|
|
420
|
|
|
//==================================== CONNECT ============================================== |
421
|
|
|
|
422
|
|
|
/** |
423
|
|
|
* easy access to the connection |
424
|
|
|
* |
425
|
|
|
*/ |
426
|
|
View Code Duplication |
public function FacebookConnect() |
|
|
|
|
427
|
|
|
{ |
428
|
|
|
if ($this->isAjax()) { |
429
|
|
|
return $this->connectUser($this->Link('FinishFacebook')); |
430
|
|
|
} else { |
431
|
|
|
Session::set("BackURL", $this->returnURL()); |
432
|
|
|
return $this->connectUser($this->returnURL()); |
433
|
|
|
} |
434
|
|
|
} |
435
|
|
|
|
436
|
|
|
/** |
437
|
|
|
* STEP 1 of the connecting process |
438
|
|
|
* @param String $returnTo - the URL to return to |
439
|
|
|
* @param Array $extra - additional paramaters |
440
|
|
|
*/ |
441
|
|
|
public function connectUser($returnTo = '', array $extra = array()) |
|
|
|
|
442
|
|
|
{ |
443
|
|
|
$facebook = self::get_facebook_sdk_class($getEvenWithoutCurrentMember = true); |
444
|
|
|
$user = $facebook->getUser(); |
445
|
|
|
$data = self::get_current_user(); |
|
|
|
|
446
|
|
|
$token = SecurityToken::inst(); |
447
|
|
|
$returnTo = urlencode($returnTo); |
448
|
|
|
$returnTo = $token->addToUrl($returnTo); |
449
|
|
|
$callback = $this->AbsoluteLink('Connect?BackURL=' . $returnTo); |
450
|
|
|
$callback = $token->addToUrl($callback); |
451
|
|
|
if (self::$permissions) { |
|
|
|
|
452
|
|
|
$extra += array( |
453
|
|
|
'scope' => implode(', ', self::$permissions) |
454
|
|
|
); |
455
|
|
|
} |
456
|
|
View Code Duplication |
if ($user && empty($extra)) { |
|
|
|
|
457
|
|
|
return self::curr()->redirect($callback); |
458
|
|
|
} else { |
459
|
|
|
return self::curr()->redirect( |
460
|
|
|
$facebook->getLoginUrl( |
461
|
|
|
array( |
462
|
|
|
'redirect_uri' => $callback |
463
|
|
|
) |
464
|
|
|
+ $extra |
465
|
|
|
) |
466
|
|
|
); |
467
|
|
|
} |
468
|
|
|
} |
469
|
|
|
|
470
|
|
|
/** |
471
|
|
|
* Connects the current user. |
472
|
|
|
* completes connecting process |
473
|
|
|
* @param SS_HTTPRequest $reg |
|
|
|
|
474
|
|
|
*/ |
475
|
|
|
public function Connect(SS_HTTPRequest $req) |
476
|
|
|
{ |
477
|
|
|
//security |
478
|
|
|
$token = SecurityToken::inst(); |
479
|
|
|
if (!$token->checkRequest($req)) { |
480
|
|
|
return $this->httpError(400); |
481
|
|
|
} |
482
|
|
|
|
483
|
|
|
$data = null; |
484
|
|
|
|
485
|
|
|
if ($req->getVars() && !$req->getVar('error')) { |
486
|
|
|
$facebook = self::get_facebook_sdk_class($getEvenWithoutCurrentMember = true); |
487
|
|
|
$user = $facebook->getUser(); |
488
|
|
|
$data = self::get_current_user(); |
489
|
|
|
} |
490
|
|
|
if ($data && $user && is_numeric($user)) { |
491
|
|
|
$this->updateUserFromFacebookData($user, $data, false); |
|
|
|
|
492
|
|
|
} |
493
|
|
|
$returnURL = $this->returnURL(); |
494
|
|
|
return $this->redirect($returnURL); |
495
|
|
|
} |
496
|
|
|
|
497
|
|
|
/** |
498
|
|
|
* finish the login from facebook |
499
|
|
|
* @param HTTPRequest $request |
500
|
|
|
* @return String Javascript |
501
|
|
|
*/ |
502
|
|
|
public function FinishFacebook($request) |
503
|
|
|
{ |
504
|
|
|
$token = SecurityToken::inst(); |
505
|
|
|
if (!$token->checkRequest($request)) { |
|
|
|
|
506
|
|
|
return $this->httpError(400); |
507
|
|
|
} |
508
|
|
|
|
509
|
|
|
$member = Member::currentUser(); |
510
|
|
|
if ($member && $member->FacebookID) { |
511
|
|
|
return '<script type="text/javascript">//<![CDATA[ |
512
|
|
|
opener.FacebookResponse(' . \Convert::raw2json(array( |
513
|
|
|
'name' => $member->FacebookName, |
514
|
|
|
'pages' => $member->getFacebookPages(), |
515
|
|
|
'removeLink' => $token->addToUrl($this->Link('RemoveFacebook')), |
516
|
|
|
)) . '); |
517
|
|
|
window.close(); |
518
|
|
|
//]]></script>'; |
519
|
|
|
} else { |
520
|
|
|
return '<script type="text/javascript">window.close();</script>'; |
521
|
|
|
} |
522
|
|
|
} |
523
|
|
|
|
524
|
|
|
|
525
|
|
|
|
526
|
|
|
|
527
|
|
|
|
528
|
|
|
|
529
|
|
|
//==================================== LOGIN ============================================== |
530
|
|
|
|
531
|
|
|
public function loginUser(array $extra = array(), $return = false) |
|
|
|
|
532
|
|
|
{ |
533
|
|
|
$facebook = self::get_facebook_sdk_class($getEvenWithoutCurrentMember = true); |
534
|
|
|
$user = $facebook->getUser(); |
535
|
|
|
$data = self::get_current_user(); |
|
|
|
|
536
|
|
|
$token = SecurityToken::inst(); |
537
|
|
|
if ($return) { |
538
|
|
|
$return = $token->addToUrl($return); |
|
|
|
|
539
|
|
|
$return = urlencode($return); |
540
|
|
|
} |
541
|
|
|
$callback = $this->AbsoluteLink('Login' . ($return ? '?ret=' . $return : '')); |
542
|
|
|
$callback = $token->addToUrl($callback); |
543
|
|
|
if (self::$permissions) { |
|
|
|
|
544
|
|
|
$perms = self::$permissions; |
545
|
|
|
} else { |
546
|
|
|
$perms = array(); |
547
|
|
|
} |
548
|
|
|
if ($perms) { |
|
|
|
|
549
|
|
|
$extra += array( |
550
|
|
|
'scope' => implode(', ', $perms) |
551
|
|
|
); |
552
|
|
|
} |
553
|
|
|
|
554
|
|
View Code Duplication |
if ($user && empty($extra)) { |
|
|
|
|
555
|
|
|
return self::curr()->redirect($callback); |
556
|
|
|
} else { |
557
|
|
|
return self::curr()->redirect($facebook->getLoginUrl(array( |
558
|
|
|
'redirect_uri' => $callback, |
559
|
|
|
) + $extra)); |
560
|
|
|
} |
561
|
|
|
} |
562
|
|
|
|
563
|
|
|
public function Login(SS_HTTPRequest $req) |
564
|
|
|
{ |
565
|
|
|
//security |
566
|
|
|
$token = SecurityToken::inst(); |
567
|
|
|
if (!$token->checkRequest($req)) { |
568
|
|
|
return $this->httpError(400); |
569
|
|
|
} |
570
|
|
|
|
571
|
|
|
//denied! |
572
|
|
|
if ($req->getVar('denied') || $req->getVar('error_reason') == 'user_denied') { |
573
|
|
|
Session::set('FormInfo.FacebookLoginForm_LoginForm.formError.message', 'Login cancelled.'); |
574
|
|
|
Session::set('FormInfo.FacebookLoginForm_LoginForm.formError.type', 'error'); |
575
|
|
|
return $this->redirect('Security/login#FacebookLoginForm_LoginForm_tab'); |
576
|
|
|
} |
577
|
|
|
$facebook = self::get_facebook_sdk_class($getEvenWithoutCurrentMember = true); |
578
|
|
|
$user = $facebook->getUser(); |
579
|
|
|
$data = self::get_current_user(); |
580
|
|
|
$error = ""; |
581
|
|
|
if (!$user) { |
582
|
|
|
$error = 'Login cancelled.'; |
|
|
|
|
583
|
|
|
return $this->redirect('Security/login#FacebookLoginForm_LoginForm_tab'); |
584
|
|
|
} |
585
|
|
|
if ($error) { |
586
|
|
|
Session::set('FormInfo.FacebookLoginForm_LoginForm.formError.message', 'Login error: ' . $data->error->message); |
587
|
|
|
Session::set('FormInfo.FacebookLoginForm_LoginForm.formError.type', 'error'); |
588
|
|
|
return $this->redirect('Security/login#FacebookLoginForm_LoginForm_tab'); |
589
|
|
|
} |
590
|
|
|
$this->updateUserFromFacebookData($user, $data, $keepLoggedIn = Session::get('SessionForms.FacebookLoginForm.Remember')); |
591
|
|
|
Session::clear('SessionForms.FacebookLoginForm.Remember'); |
592
|
|
|
return $this->redirect($this->returnURL()); |
593
|
|
|
} |
594
|
|
|
|
595
|
|
|
|
596
|
|
|
|
597
|
|
|
//========================================== REMOVE ===================================== |
598
|
|
|
|
599
|
|
|
/** |
600
|
|
|
* alias for RemoveFaceBook |
601
|
|
|
*/ |
602
|
|
View Code Duplication |
public function remove($request = null) |
|
|
|
|
603
|
|
|
{ |
604
|
|
|
$token = SecurityToken::inst(); |
605
|
|
|
if (!$token->checkRequest($request)) { |
606
|
|
|
return $this->httpError(400); |
607
|
|
|
} |
608
|
|
|
return $this->RemoveFacebook($request); |
609
|
|
|
} |
610
|
|
|
|
611
|
|
|
/** |
612
|
|
|
* remove connection to facebook |
613
|
|
|
* TO DO: remove links |
614
|
|
|
* TO DO: FB session |
615
|
|
|
* @param HTTPRequest |
616
|
|
|
*/ |
617
|
|
|
public function RemoveFacebook($request) |
|
|
|
|
618
|
|
|
{ |
619
|
|
|
//security check |
620
|
|
|
// |
621
|
|
|
$m = $this->CurrentMember(); |
622
|
|
|
if ($m) { |
623
|
|
|
$m->FacebookID = 0; |
624
|
|
|
$m->FacebookURL = ""; |
625
|
|
|
$m->FacebookPicture = ""; |
626
|
|
|
$m->FacebookName = ""; |
627
|
|
|
$m->FacebookEmail = ""; |
628
|
|
|
$m->FacebookFirstName = ""; |
629
|
|
|
$m->FacebookMiddleName = ""; |
630
|
|
|
$m->FacebookLastName = ""; |
631
|
|
|
$m->FacebookUsername = ""; |
632
|
|
|
$m->write(); |
633
|
|
|
} |
634
|
|
|
$facebook = new Facebook(array( |
635
|
|
|
'appId' => self::$facebook_id, |
636
|
|
|
'secret' => self::$facebook_secret |
637
|
|
|
)); |
638
|
|
|
//do we need to encode URL ???? |
639
|
|
|
$url = $facebook->getLogoutUrl(array("next" => $this->returnURL(true))); |
640
|
|
|
$this->redirect($url); |
641
|
|
|
} |
642
|
|
|
|
643
|
|
|
//========================================== HELPER METHODS ===================================== |
644
|
|
|
|
645
|
|
|
|
646
|
|
|
|
647
|
|
|
|
648
|
|
|
/** |
649
|
|
|
* Saves the FB data to the member and logs in the member if that has not been done yet. |
650
|
|
|
* @param Int $user - the ID of the current twitter user |
651
|
|
|
* @param Object $facebookData - the data returned from FB |
652
|
|
|
* @param Boolean $keepLoggedIn - does the user stay logged in |
653
|
|
|
* @return Member |
654
|
|
|
*/ |
655
|
|
|
protected function updateUserFromFacebookData($user, $facebookData, $keepLoggedIn = false) |
656
|
|
|
{ |
657
|
|
|
//clean up data |
658
|
|
|
if (is_array($facebookData)) { |
659
|
|
|
$obj = new DataObject(); |
660
|
|
|
foreach ($facebookData as $key => $value) { |
661
|
|
|
$obj->$key = $value; |
662
|
|
|
} |
663
|
|
|
$facebookData = $obj; |
664
|
|
|
} |
665
|
|
|
|
666
|
|
|
//find member |
667
|
|
|
$member = null; |
668
|
|
|
if ($user) { |
669
|
|
|
$member = DataObject::get_one('Member', '"FacebookID" = \'' . Convert::raw2sql($user) . '\''); |
670
|
|
|
} |
671
|
|
|
if (!$member) { |
672
|
|
|
$member = Member::currentUser(); |
673
|
|
|
if (!$member) { |
674
|
|
|
$member = new Member(); |
675
|
|
|
} |
676
|
|
|
} |
677
|
|
|
//check if anyone else uses the email: |
678
|
|
View Code Duplication |
if ($facebookEmail = Convert::raw2sql($facebookData->email)) { |
|
|
|
|
679
|
|
|
$memberID = intval($member->ID)-0; |
680
|
|
|
$existingMember = DataObject::get_one( |
681
|
|
|
'Member', |
682
|
|
|
'("Email" = \'' . $facebookEmail . '\' OR "FacebookEmail" = \''.$facebookEmail.'\') AND "Member"."ID" <> '.$memberID |
683
|
|
|
); |
684
|
|
|
if ($existingMember) { |
685
|
|
|
$member = $existingMember; |
686
|
|
|
} |
687
|
|
|
} |
688
|
|
|
$member->FacebookID = empty($user) ? 0 : $user; |
689
|
|
|
$member->FacebookURL = empty($facebookData->link) ? "" : $facebookData->link; |
690
|
|
|
$member->FacebookPicture = empty($facebookData->picture) ? "" : $facebookData->picture; |
691
|
|
|
$member->FacebookName = empty($facebookData->name) ? "" : $facebookData->name; |
692
|
|
|
; |
693
|
|
|
$member->FacebookEmail = empty($facebookData->email) ? "" : $facebookData->email; |
694
|
|
|
$member->FacebookFirstName = empty($facebookData->first_name) ? "" : $facebookData->first_name; |
695
|
|
|
$member->FacebookMiddleName = empty($facebookData->middle_name) ? "" : $facebookData->middle_name; |
696
|
|
|
$member->FacebookLastName = empty($facebookData->last_name) ? "" : $facebookData->last_name; |
697
|
|
|
$member->FacebookUsername = empty($facebookData->username) ? "" : $facebookData->username; |
698
|
|
|
if (!$member->FirstName) { |
699
|
|
|
$member->FirstName = $member->FacebookFirstName; |
700
|
|
|
} |
701
|
|
|
if (!$member->Surname) { |
702
|
|
|
$member->Surname = $member->FacebookLastName; |
703
|
|
|
} |
704
|
|
|
if (!empty($facebookData->email)) { |
705
|
|
|
if (!$member->Email) { |
706
|
|
|
$memberID = intval($member->ID)-0; |
707
|
|
|
$anotherMemberWithThisEmail = DataObject::get_one( |
708
|
|
|
'Member', |
709
|
|
|
'("Email" = \'' . $facebookData->email . '\' OR "FacebookEmail" = \''.$facebookData->email.'\') AND "Member"."ID" <> '.$memberID |
710
|
|
|
); |
711
|
|
|
if (!$anotherMemberWithThisEmail) { |
712
|
|
|
$member->Email = $facebookData->email; |
713
|
|
|
} |
714
|
|
|
} |
715
|
|
|
} |
716
|
|
|
$member->write(); |
717
|
|
|
$oldMember = Member::currentUser(); |
718
|
|
View Code Duplication |
if ($oldMember) { |
|
|
|
|
719
|
|
|
if ($oldMember->ID != $member->ID) { |
720
|
|
|
$oldMember->logout(); |
721
|
|
|
$member->login($keepLoggedIn); |
722
|
|
|
} else { |
|
|
|
|
723
|
|
|
//already logged in - nothing to do. |
724
|
|
|
} |
725
|
|
|
} else { |
726
|
|
|
$member->login($keepLoggedIn); |
727
|
|
|
} |
728
|
|
|
return $member; |
729
|
|
|
} |
730
|
|
|
|
731
|
|
|
|
732
|
|
|
/** |
733
|
|
|
* retrieve the various identities this user has on Facebook |
734
|
|
|
* |
735
|
|
|
* @return Array |
736
|
|
|
*/ |
737
|
|
|
public function getFacebookPages() |
738
|
|
|
{ |
739
|
|
|
$facebook = self::get_facebook_sdk_class(); |
740
|
|
|
$user = $facebook->getUser(); |
741
|
|
|
if ($user) { |
742
|
|
|
$pages = array( |
743
|
|
|
'me/feed' => 'Personal Page' |
744
|
|
|
); |
745
|
|
|
try { |
746
|
|
|
$resp = $facebook->api('/me/accounts', 'GET'); |
747
|
|
|
if (isset($resp->data)) { |
748
|
|
|
foreach ($resp->data as $app) { |
749
|
|
|
if ($app->category != 'Application') { |
750
|
|
|
$pages[$app->id] = $app->name . ' <small>(' . $app->category . ')</small>'; |
751
|
|
|
} |
752
|
|
|
} |
753
|
|
|
} |
754
|
|
|
} catch (FacebookApiException $e) { |
|
|
|
|
755
|
|
|
SS_Log::log($e, SS_Log::ERR); |
756
|
|
|
} |
757
|
|
|
return $pages; |
758
|
|
|
} |
759
|
|
|
return array(); |
760
|
|
|
} |
761
|
|
|
|
762
|
|
|
|
763
|
|
|
|
764
|
|
|
public function meondatabase() |
765
|
|
|
{ |
766
|
|
|
$member = Member::currentUser(); |
767
|
|
|
if ($member) { |
768
|
|
|
echo "<ul>"; |
769
|
|
|
echo "<li>FacebookID: ".$member->FacebookID."</li>"; |
770
|
|
|
echo "<li>FacebookName: ".$member->FacebookName."</li>"; |
771
|
|
|
echo "<li>FacebookEmail: ".$member->FacebookEmail."</li>"; |
772
|
|
|
echo "<li>FacebookFirstName: ".$member->FacebookFirstName."</li>"; |
773
|
|
|
echo "<li>FacebookMiddleName: ".$member->FacebookMiddleName."</li>"; |
774
|
|
|
echo "<li>FacebookLastName: ".$member->FacebookLastName."</li>"; |
775
|
|
|
echo "<li>FacebookUsername: ".$member->FacebookUsername."</li>"; |
776
|
|
|
echo "<li>FacebookPicture: <img src=\"".$member->FacebookPicture."\" alt=\"\" /></li>"; |
777
|
|
|
echo "<li>FacebookURL: <a href=\"".$member->FacebookURL."\" />click ".$member->FacebookURL."</a></li>"; |
778
|
|
|
echo "</ul>"; |
779
|
|
|
} else { |
780
|
|
|
echo "<h2>You are not logged in.</h2>"; |
781
|
|
|
} |
782
|
|
|
} |
783
|
|
|
} |
784
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.