Mercurial > hg > ywww
comparison facebook.php @ 6:077b0a0a3e6d
remaining originals according to dependency walk
author | Robert Boland <robert@markup.co.uk> |
---|---|
date | Thu, 16 Feb 2017 22:29:02 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
5:55445b456ad0 | 6:077b0a0a3e6d |
---|---|
1 <?php | |
2 | |
3 if (!function_exists('curl_init')) { | |
4 throw new Exception('Facebook needs the CURL PHP extension.'); | |
5 } | |
6 if (!function_exists('json_decode')) { | |
7 throw new Exception('Facebook needs the JSON PHP extension.'); | |
8 } | |
9 | |
10 /** | |
11 * Thrown when an API call returns an exception. | |
12 * | |
13 * @author Naitik Shah <naitik@facebook.com> | |
14 */ | |
15 class FacebookApiException extends Exception | |
16 { | |
17 /** | |
18 * The result from the API server that represents the exception information. | |
19 */ | |
20 protected $result; | |
21 | |
22 /** | |
23 * Make a new API Exception with the given result. | |
24 * | |
25 * @param Array $result the result from the API server | |
26 */ | |
27 public function __construct($result) { | |
28 $this->result = $result; | |
29 | |
30 $code = isset($result['error_code']) ? $result['error_code'] : 0; | |
31 $msg = isset($result['error']) | |
32 ? $result['error']['message'] : $result['error_msg']; | |
33 parent::__construct($msg, $code); | |
34 } | |
35 | |
36 /** | |
37 * Return the associated result object returned by the API server. | |
38 * | |
39 * @returns Array the result from the API server | |
40 */ | |
41 public function getResult() { | |
42 return $this->result; | |
43 } | |
44 | |
45 /** | |
46 * Returns the associated type for the error. This will default to | |
47 * 'Exception' when a type is not available. | |
48 * | |
49 * @return String | |
50 */ | |
51 public function getType() { | |
52 return | |
53 isset($this->result['error']) && isset($this->result['error']['type']) | |
54 ? $this->result['error']['type'] | |
55 : 'Exception'; | |
56 } | |
57 | |
58 /** | |
59 * To make debugging easier. | |
60 * | |
61 * @returns String the string representation of the error | |
62 */ | |
63 public function __toString() { | |
64 $str = $this->getType() . ': '; | |
65 if ($this->code != 0) { | |
66 $str .= $this->code . ': '; | |
67 } | |
68 return $str . $this->message; | |
69 } | |
70 } | |
71 | |
72 /** | |
73 * Provides access to the Facebook Platform. | |
74 * | |
75 * @author Naitik Shah <naitik@facebook.com> | |
76 */ | |
77 class Facebook | |
78 { | |
79 /** | |
80 * Version. | |
81 */ | |
82 const VERSION = '2.0.5'; | |
83 | |
84 /** | |
85 * Default options for curl. | |
86 */ | |
87 public static $CURL_OPTS = array( | |
88 CURLOPT_CONNECTTIMEOUT => 10, | |
89 CURLOPT_RETURNTRANSFER => true, | |
90 CURLOPT_TIMEOUT => 60, | |
91 CURLOPT_USERAGENT => 'facebook-php-2.0', | |
92 ); | |
93 | |
94 /** | |
95 * List of query parameters that get automatically dropped when rebuilding | |
96 * the current URL. | |
97 */ | |
98 protected static $DROP_QUERY_PARAMS = array( | |
99 'session', | |
100 ); | |
101 | |
102 /** | |
103 * Maps aliases to Facebook domains. | |
104 */ | |
105 public static $DOMAIN_MAP = array( | |
106 'api' => 'https://api.facebook.com/', | |
107 'api_read' => 'https://api-read.facebook.com/', | |
108 'graph' => 'https://graph.facebook.com/', | |
109 'www' => 'https://www.facebook.com/', | |
110 ); | |
111 | |
112 /** | |
113 * The Application ID. | |
114 */ | |
115 protected $appId; | |
116 | |
117 /** | |
118 * The Application API Secret. | |
119 */ | |
120 protected $apiSecret; | |
121 | |
122 /** | |
123 * The active user session, if one is available. | |
124 */ | |
125 protected $session; | |
126 | |
127 /** | |
128 * Indicates that we already loaded the session as best as we could. | |
129 */ | |
130 protected $sessionLoaded = false; | |
131 | |
132 /** | |
133 * Indicates if Cookie support should be enabled. | |
134 */ | |
135 protected $cookieSupport = false; | |
136 | |
137 /** | |
138 * Base domain for the Cookie. | |
139 */ | |
140 protected $baseDomain = ''; | |
141 | |
142 /** | |
143 * Initialize a Facebook Application. | |
144 * | |
145 * The configuration: | |
146 * - appId: the application ID | |
147 * - secret: the application secret | |
148 * - cookie: (optional) boolean true to enable cookie support | |
149 * - domain: (optional) domain for the cookie | |
150 * | |
151 * @param Array $config the application configuration | |
152 */ | |
153 public function __construct($config) { | |
154 $this->setAppId($config['appId']); | |
155 $this->setApiSecret($config['secret']); | |
156 if (isset($config['cookie'])) { | |
157 $this->setCookieSupport($config['cookie']); | |
158 } | |
159 if (isset($config['domain'])) { | |
160 $this->setBaseDomain($config['domain']); | |
161 } | |
162 } | |
163 | |
164 /** | |
165 * Set the Application ID. | |
166 * | |
167 * @param String $appId the Application ID | |
168 */ | |
169 public function setAppId($appId) { | |
170 $this->appId = $appId; | |
171 return $this; | |
172 } | |
173 | |
174 /** | |
175 * Get the Application ID. | |
176 * | |
177 * @return String the Application ID | |
178 */ | |
179 public function getAppId() { | |
180 return $this->appId; | |
181 } | |
182 | |
183 /** | |
184 * Set the API Secret. | |
185 * | |
186 * @param String $appId the API Secret | |
187 */ | |
188 public function setApiSecret($apiSecret) { | |
189 $this->apiSecret = $apiSecret; | |
190 return $this; | |
191 } | |
192 | |
193 /** | |
194 * Get the API Secret. | |
195 * | |
196 * @return String the API Secret | |
197 */ | |
198 public function getApiSecret() { | |
199 return $this->apiSecret; | |
200 } | |
201 | |
202 /** | |
203 * Set the Cookie Support status. | |
204 * | |
205 * @param Boolean $cookieSupport the Cookie Support status | |
206 */ | |
207 public function setCookieSupport($cookieSupport) { | |
208 $this->cookieSupport = $cookieSupport; | |
209 return $this; | |
210 } | |
211 | |
212 /** | |
213 * Get the Cookie Support status. | |
214 * | |
215 * @return Boolean the Cookie Support status | |
216 */ | |
217 public function useCookieSupport() { | |
218 return $this->cookieSupport; | |
219 } | |
220 | |
221 /** | |
222 * Set the base domain for the Cookie. | |
223 * | |
224 * @param String $domain the base domain | |
225 */ | |
226 public function setBaseDomain($domain) { | |
227 $this->baseDomain = $domain; | |
228 return $this; | |
229 } | |
230 | |
231 /** | |
232 * Get the base domain for the Cookie. | |
233 * | |
234 * @return String the base domain | |
235 */ | |
236 public function getBaseDomain() { | |
237 return $this->baseDomain; | |
238 } | |
239 | |
240 /** | |
241 * Set the Session. | |
242 * | |
243 * @param Array $session the session | |
244 * @param Boolean $write_cookie indicate if a cookie should be written. this | |
245 * value is ignored if cookie support has been disabled. | |
246 */ | |
247 public function setSession($session=null, $write_cookie=true) { | |
248 $session = $this->validateSessionObject($session); | |
249 $this->sessionLoaded = true; | |
250 $this->session = $session; | |
251 if ($write_cookie) { | |
252 $this->setCookieFromSession($session); | |
253 } | |
254 return $this; | |
255 } | |
256 | |
257 /** | |
258 * Get the session object. This will automatically look for a signed session | |
259 * sent via the Cookie or Query Parameters if needed. | |
260 * | |
261 * @return Array the session | |
262 */ | |
263 public function getSession() { | |
264 if (!$this->sessionLoaded) { | |
265 $session = null; | |
266 $write_cookie = true; | |
267 | |
268 // try loading session from $_REQUEST | |
269 if (isset($_REQUEST['session'])) { | |
270 $session = json_decode( | |
271 get_magic_quotes_gpc() | |
272 ? stripslashes(urldecode($_REQUEST['session'])) | |
273 : urldecode($_REQUEST['session']), | |
274 true | |
275 ); | |
276 $session = $this->validateSessionObject($session); | |
277 } | |
278 | |
279 // try loading session from cookie if necessary | |
280 if (!$session && $this->useCookieSupport()) { | |
281 $cookieName = $this->getSessionCookieName(); | |
282 if (isset($_COOKIE[$cookieName])) { | |
283 $session = array(); | |
284 parse_str(trim( | |
285 get_magic_quotes_gpc() | |
286 ? stripslashes($_COOKIE[$cookieName]) | |
287 : $_COOKIE[$cookieName], | |
288 '"' | |
289 ), $session); | |
290 $session = $this->validateSessionObject($session); | |
291 // write only if we need to delete a invalid session cookie | |
292 $write_cookie = empty($session); | |
293 } | |
294 } | |
295 | |
296 $this->setSession($session, $write_cookie); | |
297 } | |
298 | |
299 return $this->session; | |
300 } | |
301 | |
302 /** | |
303 * Get the UID from the session. | |
304 * | |
305 * @return String the UID if available | |
306 */ | |
307 public function getUser() { | |
308 $session = $this->getSession(); | |
309 return $session ? $session['uid'] : null; | |
310 } | |
311 | |
312 /** | |
313 * Get a Login URL for use with redirects. By default, full page redirect is | |
314 * assumed. If you are using the generated URL with a window.open() call in | |
315 * JavaScript, you can pass in display=popup as part of the $params. | |
316 * | |
317 * The parameters: | |
318 * - next: the url to go to after a successful login | |
319 * - cancel_url: the url to go to after the user cancels | |
320 * - req_perms: comma separated list of requested extended perms | |
321 * - display: can be "page" (default, full page) or "popup" | |
322 * | |
323 * @param Array $params provide custom parameters | |
324 * @return String the URL for the login flow | |
325 */ | |
326 public function getLoginUrl($params=array()) { | |
327 $currentUrl = $this->getCurrentUrl(); | |
328 return $this->getUrl( | |
329 'www', | |
330 'login.php', | |
331 array_merge(array( | |
332 'api_key' => $this->getAppId(), | |
333 'cancel_url' => $currentUrl, | |
334 'display' => 'page', | |
335 'fbconnect' => 1, | |
336 'next' => $currentUrl, | |
337 'return_session' => 1, | |
338 'session_version' => 3, | |
339 'v' => '1.0', | |
340 ), $params) | |
341 ); | |
342 } | |
343 | |
344 /** | |
345 * Get a Logout URL suitable for use with redirects. | |
346 * | |
347 * The parameters: | |
348 * - next: the url to go to after a successful logout | |
349 * | |
350 * @param Array $params provide custom parameters | |
351 * @return String the URL for the logout flow | |
352 */ | |
353 public function getLogoutUrl($params=array()) { | |
354 $session = $this->getSession(); | |
355 return $this->getUrl( | |
356 'www', | |
357 'logout.php', | |
358 array_merge(array( | |
359 'api_key' => $this->getAppId(), | |
360 'next' => $this->getCurrentUrl(), | |
361 'session_key' => $session['session_key'], | |
362 ), $params) | |
363 ); | |
364 } | |
365 | |
366 /** | |
367 * Get a login status URL to fetch the status from facebook. | |
368 * | |
369 * The parameters: | |
370 * - ok_session: the URL to go to if a session is found | |
371 * - no_session: the URL to go to if the user is not connected | |
372 * - no_user: the URL to go to if the user is not signed into facebook | |
373 * | |
374 * @param Array $params provide custom parameters | |
375 * @return String the URL for the logout flow | |
376 */ | |
377 public function getLoginStatusUrl($params=array()) { | |
378 return $this->getUrl( | |
379 'www', | |
380 'extern/login_status.php', | |
381 array_merge(array( | |
382 'api_key' => $this->getAppId(), | |
383 'no_session' => $this->getCurrentUrl(), | |
384 'no_user' => $this->getCurrentUrl(), | |
385 'ok_session' => $this->getCurrentUrl(), | |
386 'session_version' => 3, | |
387 ), $params) | |
388 ); | |
389 } | |
390 | |
391 /** | |
392 * Make an API call. | |
393 * | |
394 * @param Array $params the API call parameters | |
395 * @return the decoded response | |
396 */ | |
397 public function api(/* polymorphic */) { | |
398 $args = func_get_args(); | |
399 if (is_array($args[0])) { | |
400 return $this->_restserver($args[0]); | |
401 } else { | |
402 return call_user_func_array(array($this, '_graph'), $args); | |
403 } | |
404 } | |
405 | |
406 /** | |
407 * Invoke the old restserver.php endpoint. | |
408 * | |
409 * @param Array $params method call object | |
410 * @return the decoded response object | |
411 * @throws FacebookApiException | |
412 */ | |
413 protected function _restserver($params) { | |
414 // generic application level parameters | |
415 $params['api_key'] = $this->getAppId(); | |
416 $params['format'] = 'json-strings'; | |
417 | |
418 $result = json_decode($this->_oauthRequest( | |
419 $this->getApiUrl($params['method']), | |
420 $params | |
421 ), true); | |
422 | |
423 // results are returned, errors are thrown | |
424 if (is_array($result) && isset($result['error_code'])) { | |
425 throw new FacebookApiException($result); | |
426 } | |
427 return $result; | |
428 } | |
429 | |
430 /** | |
431 * Invoke the Graph API. | |
432 * | |
433 * @param String $path the path (required) | |
434 * @param String $method the http method (default 'GET') | |
435 * @param Array $params the query/post data | |
436 * @return the decoded response object | |
437 * @throws FacebookApiException | |
438 */ | |
439 protected function _graph($path, $method='GET', $params=array()) { | |
440 if (is_array($method) && empty($params)) { | |
441 $params = $method; | |
442 $method = 'GET'; | |
443 } | |
444 $params['method'] = $method; // method override as we always do a POST | |
445 | |
446 $result = json_decode($this->_oauthRequest( | |
447 $this->getUrl('graph', $path), | |
448 $params | |
449 ), true); | |
450 | |
451 // results are returned, errors are thrown | |
452 if (is_array($result) && isset($result['error'])) { | |
453 $e = new FacebookApiException($result); | |
454 if ($e->getType() === 'OAuthException') { | |
455 $this->setSession(null); | |
456 } | |
457 throw $e; | |
458 } | |
459 return $result; | |
460 } | |
461 | |
462 /** | |
463 * Make a OAuth Request | |
464 * | |
465 * @param String $path the path (required) | |
466 * @param Array $params the query/post data | |
467 * @return the decoded response object | |
468 * @throws FacebookApiException | |
469 */ | |
470 protected function _oauthRequest($url, $params) { | |
471 if (!isset($params['access_token'])) { | |
472 $session = $this->getSession(); | |
473 // either user session signed, or app signed | |
474 if ($session) { | |
475 $params['access_token'] = $session['access_token']; | |
476 } else { | |
477 $params['access_token'] = $this->getAppId() .'|'. $this->getApiSecret(); | |
478 } | |
479 } | |
480 | |
481 // json_encode all params values that are not strings | |
482 foreach ($params as $key => $value) { | |
483 if (!is_string($value)) { | |
484 $params[$key] = json_encode($value); | |
485 } | |
486 } | |
487 return $this->makeRequest($url, $params); | |
488 } | |
489 | |
490 /** | |
491 * Makes an HTTP request. This method can be overriden by subclasses if | |
492 * developers want to do fancier things or use something other than curl to | |
493 * make the request. | |
494 * | |
495 * @param String $url the URL to make the request to | |
496 * @param Array $params the parameters to use for the POST body | |
497 * @param CurlHandler $ch optional initialized curl handle | |
498 * @return String the response text | |
499 */ | |
500 protected function makeRequest($url, $params, $ch=null) { | |
501 if (!$ch) { | |
502 $ch = curl_init(); | |
503 } | |
504 | |
505 $opts = self::$CURL_OPTS; | |
506 $opts[CURLOPT_POSTFIELDS] = http_build_query($params, null, '&'); | |
507 $opts[CURLOPT_URL] = $url; | |
508 curl_setopt_array($ch, $opts); | |
509 $result = curl_exec($ch); | |
510 if ($result === false) { | |
511 $e = new FacebookApiException(array( | |
512 'error_code' => curl_errno($ch), | |
513 'error' => array( | |
514 'message' => curl_error($ch), | |
515 'type' => 'CurlException', | |
516 ), | |
517 )); | |
518 curl_close($ch); | |
519 throw $e; | |
520 } | |
521 curl_close($ch); | |
522 return $result; | |
523 } | |
524 | |
525 /** | |
526 * The name of the Cookie that contains the session. | |
527 * | |
528 * @return String the cookie name | |
529 */ | |
530 protected function getSessionCookieName() { | |
531 return 'fbs_' . $this->getAppId(); | |
532 } | |
533 | |
534 /** | |
535 * Set a JS Cookie based on the _passed in_ session. It does not use the | |
536 * currently stored session -- you need to explicitly pass it in. | |
537 * | |
538 * @param Array $session the session to use for setting the cookie | |
539 */ | |
540 protected function setCookieFromSession($session=null) { | |
541 if (!$this->useCookieSupport()) { | |
542 return; | |
543 } | |
544 | |
545 $cookieName = $this->getSessionCookieName(); | |
546 $value = 'deleted'; | |
547 $expires = time() - 3600; | |
548 $domain = $this->getBaseDomain(); | |
549 if ($session) { | |
550 $value = '"' . http_build_query($session, null, '&') . '"'; | |
551 if (isset($session['base_domain'])) { | |
552 $domain = $session['base_domain']; | |
553 } | |
554 $expires = $session['expires']; | |
555 } | |
556 | |
557 // prepend dot if a domain is found | |
558 if ($domain) { | |
559 $domain = '.' . $domain; | |
560 } | |
561 | |
562 // if an existing cookie is not set, we dont need to delete it | |
563 if ($value == 'deleted' && empty($_COOKIE[$cookieName])) { | |
564 return; | |
565 } | |
566 | |
567 if (headers_sent()) { | |
568 // disable error log if we are running in a CLI environment | |
569 // @codeCoverageIgnoreStart | |
570 if (php_sapi_name() != 'cli') { | |
571 error_log('Could not set cookie. Headers already sent.'); | |
572 } | |
573 // @codeCoverageIgnoreEnd | |
574 | |
575 // ignore for code coverage as we will never be able to setcookie in a CLI | |
576 // environment | |
577 // @codeCoverageIgnoreStart | |
578 } else { | |
579 setcookie($cookieName, $value, $expires, '/', $domain); | |
580 } | |
581 // @codeCoverageIgnoreEnd | |
582 } | |
583 | |
584 /** | |
585 * Validates a session_version=3 style session object. | |
586 * | |
587 * @param Array $session the session object | |
588 * @return Array the session object if it validates, null otherwise | |
589 */ | |
590 protected function validateSessionObject($session) { | |
591 // make sure some essential fields exist | |
592 if (is_array($session) && | |
593 isset($session['uid']) && | |
594 isset($session['session_key']) && | |
595 isset($session['secret']) && | |
596 isset($session['access_token']) && | |
597 isset($session['sig'])) { | |
598 // validate the signature | |
599 $session_without_sig = $session; | |
600 unset($session_without_sig['sig']); | |
601 $expected_sig = self::generateSignature( | |
602 $session_without_sig, | |
603 $this->getApiSecret() | |
604 ); | |
605 if ($session['sig'] != $expected_sig) { | |
606 // disable error log if we are running in a CLI environment | |
607 // @codeCoverageIgnoreStart | |
608 if (php_sapi_name() != 'cli') { | |
609 error_log('Got invalid session signature in cookie.'); | |
610 } | |
611 // @codeCoverageIgnoreEnd | |
612 $session = null; | |
613 } | |
614 // check expiry time | |
615 } else { | |
616 $session = null; | |
617 } | |
618 return $session; | |
619 } | |
620 | |
621 /** | |
622 * Build the URL for api given parameters. | |
623 * | |
624 * @param $method String the method name. | |
625 * @return String the URL for the given parameters | |
626 */ | |
627 protected function getApiUrl($method) { | |
628 static $READ_ONLY_CALLS = | |
629 array('admin.getallocation' => 1, | |
630 'admin.getappproperties' => 1, | |
631 'admin.getbannedusers' => 1, | |
632 'admin.getlivestreamvialink' => 1, | |
633 'admin.getmetrics' => 1, | |
634 'admin.getrestrictioninfo' => 1, | |
635 'application.getpublicinfo' => 1, | |
636 'auth.getapppublickey' => 1, | |
637 'auth.getsession' => 1, | |
638 'auth.getsignedpublicsessiondata' => 1, | |
639 'comments.get' => 1, | |
640 'connect.getunconnectedfriendscount' => 1, | |
641 'dashboard.getactivity' => 1, | |
642 'dashboard.getcount' => 1, | |
643 'dashboard.getglobalnews' => 1, | |
644 'dashboard.getnews' => 1, | |
645 'dashboard.multigetcount' => 1, | |
646 'dashboard.multigetnews' => 1, | |
647 'data.getcookies' => 1, | |
648 'events.get' => 1, | |
649 'events.getmembers' => 1, | |
650 'fbml.getcustomtags' => 1, | |
651 'feed.getappfriendstories' => 1, | |
652 'feed.getregisteredtemplatebundlebyid' => 1, | |
653 'feed.getregisteredtemplatebundles' => 1, | |
654 'fql.multiquery' => 1, | |
655 'fql.query' => 1, | |
656 'friends.arefriends' => 1, | |
657 'friends.get' => 1, | |
658 'friends.getappusers' => 1, | |
659 'friends.getlists' => 1, | |
660 'friends.getmutualfriends' => 1, | |
661 'gifts.get' => 1, | |
662 'groups.get' => 1, | |
663 'groups.getmembers' => 1, | |
664 'intl.gettranslations' => 1, | |
665 'links.get' => 1, | |
666 'notes.get' => 1, | |
667 'notifications.get' => 1, | |
668 'pages.getinfo' => 1, | |
669 'pages.isadmin' => 1, | |
670 'pages.isappadded' => 1, | |
671 'pages.isfan' => 1, | |
672 'permissions.checkavailableapiaccess' => 1, | |
673 'permissions.checkgrantedapiaccess' => 1, | |
674 'photos.get' => 1, | |
675 'photos.getalbums' => 1, | |
676 'photos.gettags' => 1, | |
677 'profile.getinfo' => 1, | |
678 'profile.getinfooptions' => 1, | |
679 'stream.get' => 1, | |
680 'stream.getcomments' => 1, | |
681 'stream.getfilters' => 1, | |
682 'users.getinfo' => 1, | |
683 'users.getloggedinuser' => 1, | |
684 'users.getstandardinfo' => 1, | |
685 'users.hasapppermission' => 1, | |
686 'users.isappuser' => 1, | |
687 'users.isverified' => 1, | |
688 'video.getuploadlimits' => 1); | |
689 $name = 'api'; | |
690 if (isset($READ_ONLY_CALLS[strtolower($method)])) { | |
691 $name = 'api_read'; | |
692 } | |
693 return self::getUrl($name, 'restserver.php'); | |
694 } | |
695 | |
696 /** | |
697 * Build the URL for given domain alias, path and parameters. | |
698 * | |
699 * @param $name String the name of the domain | |
700 * @param $path String optional path (without a leading slash) | |
701 * @param $params Array optional query parameters | |
702 * @return String the URL for the given parameters | |
703 */ | |
704 protected function getUrl($name, $path='', $params=array()) { | |
705 $url = self::$DOMAIN_MAP[$name]; | |
706 if ($path) { | |
707 if ($path[0] === '/') { | |
708 $path = substr($path, 1); | |
709 } | |
710 $url .= $path; | |
711 } | |
712 if ($params) { | |
713 $url .= '?' . http_build_query($params); | |
714 } | |
715 return $url; | |
716 } | |
717 | |
718 /** | |
719 * Returns the Current URL, stripping it of known FB parameters that should | |
720 * not persist. | |
721 * | |
722 * @return String the current URL | |
723 */ | |
724 protected function getCurrentUrl() { | |
725 $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' | |
726 ? 'https://' | |
727 : 'http://'; | |
728 $currentUrl = $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; | |
729 $parts = parse_url($currentUrl); | |
730 | |
731 // drop known fb params | |
732 $query = ''; | |
733 if (!empty($parts['query'])) { | |
734 $params = array(); | |
735 parse_str($parts['query'], $params); | |
736 foreach(self::$DROP_QUERY_PARAMS as $key) { | |
737 unset($params[$key]); | |
738 } | |
739 if (!empty($params)) { | |
740 $query = '?' . http_build_query($params); | |
741 } | |
742 } | |
743 | |
744 // use port if non default | |
745 $port = | |
746 isset($parts['port']) && | |
747 (($protocol === 'http://' && $parts['port'] !== 80) || | |
748 ($protocol === 'https://' && $parts['port'] !== 443)) | |
749 ? ':' . $parts['port'] : ''; | |
750 | |
751 // rebuild | |
752 return $protocol . $parts['host'] . $port . $parts['path'] . $query; | |
753 } | |
754 | |
755 /** | |
756 * Generate a signature for the given params and secret. | |
757 * | |
758 * @param Array $params the parameters to sign | |
759 * @param String $secret the secret to sign with | |
760 * @return String the generated signature | |
761 */ | |
762 protected static function generateSignature($params, $secret) { | |
763 // work with sorted data | |
764 ksort($params); | |
765 | |
766 // generate the base string | |
767 $base_string = ''; | |
768 foreach($params as $key => $value) { | |
769 $base_string .= $key . '=' . $value; | |
770 } | |
771 $base_string .= $secret; | |
772 | |
773 return md5($base_string); | |
774 } | |
775 } |