Guest User

facebook.php

a guest
Apr 27th, 2012
216
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 27.63 KB | None | 0 0
  1. <?php
  2. /**
  3. *
  4. * Copyright 2011 Facebook, Inc.
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License"); you may
  7. * not use this file except in compliance with the License. You may obtain
  8. * a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  14. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  15. * License for the specific language governing permissions and limitations
  16. * under the License.
  17. */
  18.  
  19. if (!function_exists('curl_init')) {
  20. throw new Exception('Facebook needs the CURL PHP extension.');
  21. }
  22. if (!function_exists('json_decode')) {
  23. throw new Exception('Facebook needs the JSON PHP extension.');
  24. }
  25.  
  26. /**
  27. * Thrown when an API call returns an exception.
  28. *
  29. * @author Naitik Shah <naitik@facebook.com>
  30. */
  31. class FacebookApiException extends Exception
  32. {
  33. /**
  34. * The result from the API server that represents the exception information.
  35. */
  36. protected $result;
  37.  
  38. /**
  39. * Make a new API Exception with the given result.
  40. *
  41. * @param Array $result the result from the API server
  42. */
  43. public function __construct($result) {
  44. $this->result = $result;
  45.  
  46. $code = isset($result['error_code']) ? $result['error_code'] : 0;
  47.  
  48. if (isset($result['error_description'])) {
  49. // OAuth 2.0 Draft 10 style
  50. $msg = $result['error_description'];
  51. } else if (isset($result['error']) && is_array($result['error'])) {
  52. // OAuth 2.0 Draft 00 style
  53. $msg = $result['error']['message'];
  54. } else if (isset($result['error_msg'])) {
  55. // Rest server style
  56. $msg = $result['error_msg'];
  57. } else {
  58. $msg = 'Unknown Error. Check getResult()';
  59. }
  60.  
  61. parent::__construct($msg, $code);
  62. }
  63.  
  64. /**
  65. * Return the associated result object returned by the API server.
  66. *
  67. * @returns Array the result from the API server
  68. */
  69. public function getResult() {
  70. return $this->result;
  71. }
  72.  
  73. /**
  74. * Returns the associated type for the error. This will default to
  75. * 'Exception' when a type is not available.
  76. *
  77. * @return String
  78. */
  79. public function getType() {
  80. if (isset($this->result['error'])) {
  81. $error = $this->result['error'];
  82. if (is_string($error)) {
  83. // OAuth 2.0 Draft 10 style
  84. return $error;
  85. } else if (is_array($error)) {
  86. // OAuth 2.0 Draft 00 style
  87. if (isset($error['type'])) {
  88. return $error['type'];
  89. }
  90. }
  91. }
  92. return 'Exception';
  93. }
  94.  
  95. /**
  96. * To make debugging easier.
  97. *
  98. * @returns String the string representation of the error
  99. */
  100. public function __toString() {
  101. $str = $this->getType() . ': ';
  102. if ($this->code != 0) {
  103. $str .= $this->code . ': ';
  104. }
  105. return $str . $this->message;
  106. }
  107. }
  108.  
  109. /**
  110. * Provides access to the Facebook Platform.
  111. *
  112. * @author Naitik Shah <naitik@facebook.com>
  113. */
  114. class Facebook
  115. {
  116. /**
  117. * Version.
  118. */
  119. const VERSION = '2.1.2';
  120.  
  121. /**
  122. * Default options for curl.
  123. */
  124. public static $CURL_OPTS = array(
  125. CURLOPT_CONNECTTIMEOUT => 10,
  126. CURLOPT_RETURNTRANSFER => true,
  127. CURLOPT_TIMEOUT => 60,
  128. CURLOPT_USERAGENT => 'facebook-php-2.0',
  129. );
  130.  
  131. /**
  132. * List of query parameters that get automatically dropped when rebuilding
  133. * the current URL.
  134. */
  135. protected static $DROP_QUERY_PARAMS = array(
  136. 'session',
  137. 'signed_request',
  138. );
  139.  
  140. /**
  141. * Maps aliases to Facebook domains.
  142. */
  143. public static $DOMAIN_MAP = array(
  144. 'api' => 'https://api.facebook.com/',
  145. 'api_video' => 'https://api-video.facebook.com/',
  146. 'api_read' => 'https://api-read.facebook.com/',
  147. 'graph' => 'https://graph.facebook.com/',
  148. 'www' => 'https://www.facebook.com/',
  149. );
  150.  
  151. /**
  152. * The Application ID.
  153. */
  154. protected $appId;
  155.  
  156. /**
  157. * The Application API Secret.
  158. */
  159. protected $apiSecret;
  160.  
  161. /**
  162. * The active user session, if one is available.
  163. */
  164. protected $session;
  165.  
  166. /**
  167. * The data from the signed_request token.
  168. */
  169. protected $signedRequest;
  170.  
  171. /**
  172. * Indicates that we already loaded the session as best as we could.
  173. */
  174. protected $sessionLoaded = false;
  175.  
  176. /**
  177. * Indicates if Cookie support should be enabled.
  178. */
  179. protected $cookieSupport = false;
  180.  
  181. /**
  182. * Base domain for the Cookie.
  183. */
  184. protected $baseDomain = '';
  185.  
  186. /**
  187. * Indicates if the CURL based @ syntax for file uploads is enabled.
  188. */
  189. protected $fileUploadSupport = false;
  190.  
  191. /**
  192. * Initialize a Facebook Application.
  193. *
  194. * The configuration:
  195. * - appId: the application ID
  196. * - secret: the application secret
  197. * - cookie: (optional) boolean true to enable cookie support
  198. * - domain: (optional) domain for the cookie
  199. * - fileUpload: (optional) boolean indicating if file uploads are enabled
  200. *
  201. * @param Array $config the application configuration
  202. */
  203. public function __construct($config) {
  204. $this->setAppId($config['appId']);
  205. $this->setApiSecret($config['secret']);
  206. if (isset($config['cookie'])) {
  207. $this->setCookieSupport($config['cookie']);
  208. }
  209. if (isset($config['domain'])) {
  210. $this->setBaseDomain($config['domain']);
  211. }
  212. if (isset($config['fileUpload'])) {
  213. $this->setFileUploadSupport($config['fileUpload']);
  214. }
  215. }
  216.  
  217. /**
  218. * Set the Application ID.
  219. *
  220. * @param String $appId the Application ID
  221. */
  222. public function setAppId($appId) {
  223. $this->appId = $appId;
  224. return $this;
  225. }
  226.  
  227. /**
  228. * Get the Application ID.
  229. *
  230. * @return String the Application ID
  231. */
  232. public function getAppId() {
  233. return $this->appId;
  234. }
  235.  
  236. /**
  237. * Set the API Secret.
  238. *
  239. * @param String $appId the API Secret
  240. */
  241. public function setApiSecret($apiSecret) {
  242. $this->apiSecret = $apiSecret;
  243. return $this;
  244. }
  245.  
  246. /**
  247. * Get the API Secret.
  248. *
  249. * @return String the API Secret
  250. */
  251. public function getApiSecret() {
  252. return $this->apiSecret;
  253. }
  254.  
  255. /**
  256. * Set the Cookie Support status.
  257. *
  258. * @param Boolean $cookieSupport the Cookie Support status
  259. */
  260. public function setCookieSupport($cookieSupport) {
  261. $this->cookieSupport = $cookieSupport;
  262. return $this;
  263. }
  264.  
  265. /**
  266. * Get the Cookie Support status.
  267. *
  268. * @return Boolean the Cookie Support status
  269. */
  270. public function useCookieSupport() {
  271. return $this->cookieSupport;
  272. }
  273.  
  274. /**
  275. * Set the base domain for the Cookie.
  276. *
  277. * @param String $domain the base domain
  278. */
  279. public function setBaseDomain($domain) {
  280. $this->baseDomain = $domain;
  281. return $this;
  282. }
  283.  
  284. /**
  285. * Get the base domain for the Cookie.
  286. *
  287. * @return String the base domain
  288. */
  289. public function getBaseDomain() {
  290. return $this->baseDomain;
  291. }
  292.  
  293. /**
  294. * Set the file upload support status.
  295. *
  296. * @param String $domain the base domain
  297. */
  298. public function setFileUploadSupport($fileUploadSupport) {
  299. $this->fileUploadSupport = $fileUploadSupport;
  300. return $this;
  301. }
  302.  
  303. /**
  304. * Get the file upload support status.
  305. *
  306. * @return String the base domain
  307. */
  308. public function useFileUploadSupport() {
  309. return $this->fileUploadSupport;
  310. }
  311.  
  312. /**
  313. * Get the data from a signed_request token
  314. *
  315. * @return String the base domain
  316. */
  317. public function getSignedRequest() {
  318. if (!$this->signedRequest) {
  319. if (isset($_REQUEST['signed_request'])) {
  320. $this->signedRequest = $this->parseSignedRequest(
  321. $_REQUEST['signed_request']);
  322. }
  323. }
  324. return $this->signedRequest;
  325. }
  326.  
  327. /**
  328. * Set the Session.
  329. *
  330. * @param Array $session the session
  331. * @param Boolean $write_cookie indicate if a cookie should be written. this
  332. * value is ignored if cookie support has been disabled.
  333. */
  334. public function setSession($session=null, $write_cookie=true) {
  335. $session = $this->validateSessionObject($session);
  336. $this->sessionLoaded = true;
  337. $this->session = $session;
  338. if ($write_cookie) {
  339. $this->setCookieFromSession($session);
  340. }
  341. return $this;
  342. }
  343.  
  344. /**
  345. * Get the session object. This will automatically look for a signed session
  346. * sent via the signed_request, Cookie or Query Parameters if needed.
  347. *
  348. * @return Array the session
  349. */
  350. public function getSession() {
  351. if (!$this->sessionLoaded) {
  352. $session = null;
  353. $write_cookie = true;
  354.  
  355. // try loading session from signed_request in $_REQUEST
  356. $signedRequest = $this->getSignedRequest();
  357. if ($signedRequest) {
  358. // sig is good, use the signedRequest
  359. $session = $this->createSessionFromSignedRequest($signedRequest);
  360. }
  361.  
  362. // try loading session from $_REQUEST
  363. if (!$session && isset($_REQUEST['session'])) {
  364. $session = json_decode(
  365. get_magic_quotes_gpc()
  366. ? stripslashes($_REQUEST['session'])
  367. : $_REQUEST['session'],
  368. true
  369. );
  370. $session = $this->validateSessionObject($session);
  371. }
  372.  
  373. // try loading session from cookie if necessary
  374. if (!$session && $this->useCookieSupport()) {
  375. $cookieName = $this->getSessionCookieName();
  376. if (isset($_COOKIE[$cookieName])) {
  377. $session = array();
  378. parse_str(trim(
  379. get_magic_quotes_gpc()
  380. ? stripslashes($_COOKIE[$cookieName])
  381. : $_COOKIE[$cookieName],
  382. '"'
  383. ), $session);
  384. $session = $this->validateSessionObject($session);
  385. // write only if we need to delete a invalid session cookie
  386. $write_cookie = empty($session);
  387. }
  388. }
  389.  
  390. $this->setSession($session, $write_cookie);
  391. }
  392.  
  393. return $this->session;
  394. }
  395.  
  396. /**
  397. * Get the UID from the session.
  398. *
  399. * @return String the UID if available
  400. */
  401. public function getUser() {
  402. $session = $this->getSession();
  403. return $session ? $session['uid'] : null;
  404. }
  405.  
  406. /**
  407. * Gets a OAuth access token.
  408. *
  409. * @return String the access token
  410. */
  411. public function getAccessToken() {
  412. $session = $this->getSession();
  413. // either user session signed, or app signed
  414. if ($session) {
  415. return $session['access_token'];
  416. } else {
  417. return $this->getAppId() .'|'. $this->getApiSecret();
  418. }
  419. }
  420.  
  421. /**
  422. * Get a Login URL for use with redirects. By default, full page redirect is
  423. * assumed. If you are using the generated URL with a window.open() call in
  424. * JavaScript, you can pass in display=popup as part of the $params.
  425. *
  426. * The parameters:
  427. * - next: the url to go to after a successful login
  428. * - cancel_url: the url to go to after the user cancels
  429. * - req_perms: comma separated list of requested extended perms
  430. * - display: can be "page" (default, full page) or "popup"
  431. *
  432. * @param Array $params provide custom parameters
  433. * @return String the URL for the login flow
  434. */
  435. public function getLoginUrl($params=array()) {
  436. $currentUrl = $this->getCurrentUrl();
  437. return $this->getUrl(
  438. 'www',
  439. 'login.php',
  440. array_merge(array(
  441. 'api_key' => $this->getAppId(),
  442. 'cancel_url' => $currentUrl,
  443. 'display' => 'page',
  444. 'fbconnect' => 1,
  445. 'next' => $currentUrl,
  446. 'return_session' => 1,
  447. 'session_version' => 3,
  448. 'v' => '1.0',
  449. ), $params)
  450. );
  451. }
  452.  
  453. /**
  454. * Get a Logout URL suitable for use with redirects.
  455. *
  456. * The parameters:
  457. * - next: the url to go to after a successful logout
  458. *
  459. * @param Array $params provide custom parameters
  460. * @return String the URL for the logout flow
  461. */
  462. public function getLogoutUrl($params=array()) {
  463. return $this->getUrl(
  464. 'www',
  465. 'logout.php',
  466. array_merge(array(
  467. 'next' => $this->getCurrentUrl(),
  468. 'access_token' => $this->getAccessToken(),
  469. ), $params)
  470. );
  471. }
  472.  
  473. /**
  474. * Get a login status URL to fetch the status from facebook.
  475. *
  476. * The parameters:
  477. * - ok_session: the URL to go to if a session is found
  478. * - no_session: the URL to go to if the user is not connected
  479. * - no_user: the URL to go to if the user is not signed into facebook
  480. *
  481. * @param Array $params provide custom parameters
  482. * @return String the URL for the logout flow
  483. */
  484. public function getLoginStatusUrl($params=array()) {
  485. return $this->getUrl(
  486. 'www',
  487. 'extern/login_status.php',
  488. array_merge(array(
  489. 'api_key' => $this->getAppId(),
  490. 'no_session' => $this->getCurrentUrl(),
  491. 'no_user' => $this->getCurrentUrl(),
  492. 'ok_session' => $this->getCurrentUrl(),
  493. 'session_version' => 3,
  494. ), $params)
  495. );
  496. }
  497.  
  498. /**
  499. * Make an API call.
  500. *
  501. * @param Array $params the API call parameters
  502. * @return the decoded response
  503. */
  504. public function api(/* polymorphic */) {
  505. $args = func_get_args();
  506. if (is_array($args[0])) {
  507. return $this->_restserver($args[0]);
  508. } else {
  509. return call_user_func_array(array($this, '_graph'), $args);
  510. }
  511. }
  512.  
  513. /**
  514. * Invoke the old restserver.php endpoint.
  515. *
  516. * @param Array $params method call object
  517. * @return the decoded response object
  518. * @throws FacebookApiException
  519. */
  520. protected function _restserver($params) {
  521. // generic application level parameters
  522. $params['api_key'] = $this->getAppId();
  523. $params['format'] = 'json-strings';
  524.  
  525. $result = json_decode($this->_oauthRequest(
  526. $this->getApiUrl($params['method']),
  527. $params
  528. ), true);
  529.  
  530. // results are returned, errors are thrown
  531. if (is_array($result) && isset($result['error_code'])) {
  532. throw new FacebookApiException($result);
  533. }
  534. return $result;
  535. }
  536.  
  537. /**
  538. * Invoke the Graph API.
  539. *
  540. * @param String $path the path (required)
  541. * @param String $method the http method (default 'GET')
  542. * @param Array $params the query/post data
  543. * @return the decoded response object
  544. * @throws FacebookApiException
  545. */
  546. protected function _graph($path, $method='GET', $params=array()) {
  547. if (is_array($method) && empty($params)) {
  548. $params = $method;
  549. $method = 'GET';
  550. }
  551. $params['method'] = $method; // method override as we always do a POST
  552.  
  553. $result = json_decode($this->_oauthRequest(
  554. $this->getUrl('graph', $path),
  555. $params
  556. ), true);
  557.  
  558. // results are returned, errors are thrown
  559. if (is_array($result) && isset($result['error'])) {
  560. $e = new FacebookApiException($result);
  561. switch ($e->getType()) {
  562. // OAuth 2.0 Draft 00 style
  563. case 'OAuthException':
  564. // OAuth 2.0 Draft 10 style
  565. case 'invalid_token':
  566. $this->setSession(null);
  567. }
  568. throw $e;
  569. }
  570. return $result;
  571. }
  572.  
  573. /**
  574. * Make a OAuth Request
  575. *
  576. * @param String $path the path (required)
  577. * @param Array $params the query/post data
  578. * @return the decoded response object
  579. * @throws FacebookApiException
  580. */
  581. protected function _oauthRequest($url, $params) {
  582. if (!isset($params['access_token'])) {
  583. $params['access_token'] = $this->getAccessToken();
  584. }
  585.  
  586. // json_encode all params values that are not strings
  587. foreach ($params as $key => $value) {
  588. if (!is_string($value)) {
  589. $params[$key] = json_encode($value);
  590. }
  591. }
  592. return $this->makeRequest($url, $params);
  593. }
  594.  
  595. /**
  596. * Makes an HTTP request. This method can be overriden by subclasses if
  597. * developers want to do fancier things or use something other than curl to
  598. * make the request.
  599. *
  600. * @param String $url the URL to make the request to
  601. * @param Array $params the parameters to use for the POST body
  602. * @param CurlHandler $ch optional initialized curl handle
  603. * @return String the response text
  604. */
  605. protected function makeRequest($url, $params, $ch=null) {
  606. if (!$ch) {
  607. $ch = curl_init();
  608. }
  609.  
  610. $opts = self::$CURL_OPTS;
  611. if ($this->useFileUploadSupport()) {
  612. $opts[CURLOPT_POSTFIELDS] = $params;
  613. } else {
  614. $opts[CURLOPT_POSTFIELDS] = http_build_query($params, null, '&');
  615. }
  616. $opts[CURLOPT_URL] = $url;
  617.  
  618. // disable the 'Expect: 100-continue' behaviour. This causes CURL to wait
  619. // for 2 seconds if the server does not support this header.
  620. if (isset($opts[CURLOPT_HTTPHEADER])) {
  621. $existing_headers = $opts[CURLOPT_HTTPHEADER];
  622. $existing_headers[] = 'Expect:';
  623. $opts[CURLOPT_HTTPHEADER] = $existing_headers;
  624. } else {
  625. $opts[CURLOPT_HTTPHEADER] = array('Expect:');
  626. }
  627.  
  628. curl_setopt_array($ch, $opts);
  629. $result = curl_exec($ch);
  630.  
  631. if (curl_errno($ch) == 60) { // CURLE_SSL_CACERT
  632. self::errorLog('Invalid or no certificate authority found, using bundled information');
  633. curl_setopt($ch, CURLOPT_CAINFO,
  634. dirname(__FILE__) . '/fb_ca_chain_bundle.crt');
  635. $result = curl_exec($ch);
  636. }
  637.  
  638. if ($result === false) {
  639. $e = new FacebookApiException(array(
  640. 'error_code' => curl_errno($ch),
  641. 'error' => array(
  642. 'message' => curl_error($ch),
  643. 'type' => 'CurlException',
  644. ),
  645. ));
  646. curl_close($ch);
  647. throw $e;
  648. }
  649. curl_close($ch);
  650. return $result;
  651. }
  652.  
  653. /**
  654. * The name of the Cookie that contains the session.
  655. *
  656. * @return String the cookie name
  657. */
  658. protected function getSessionCookieName() {
  659. return 'fbs_' . $this->getAppId();
  660. }
  661.  
  662. /**
  663. * Set a JS Cookie based on the _passed in_ session. It does not use the
  664. * currently stored session -- you need to explicitly pass it in.
  665. *
  666. * @param Array $session the session to use for setting the cookie
  667. */
  668. protected function setCookieFromSession($session=null) {
  669. if (!$this->useCookieSupport()) {
  670. return;
  671. }
  672.  
  673. $cookieName = $this->getSessionCookieName();
  674. $value = 'deleted';
  675. $expires = time() - 3600;
  676. $domain = $this->getBaseDomain();
  677. if ($session) {
  678. $value = '"' . http_build_query($session, null, '&') . '"';
  679. if (isset($session['base_domain'])) {
  680. $domain = $session['base_domain'];
  681. }
  682. $expires = $session['expires'];
  683. }
  684.  
  685. // prepend dot if a domain is found
  686. if ($domain) {
  687. $domain = '.' . $domain;
  688. }
  689.  
  690. // if an existing cookie is not set, we dont need to delete it
  691. if ($value == 'deleted' && empty($_COOKIE[$cookieName])) {
  692. return;
  693. }
  694.  
  695. if (headers_sent()) {
  696. self::errorLog('Could not set cookie. Headers already sent.');
  697.  
  698. // ignore for code coverage as we will never be able to setcookie in a CLI
  699. // environment
  700. // @codeCoverageIgnoreStart
  701. } else {
  702. setcookie($cookieName, $value, $expires, '/', $domain);
  703. }
  704. // @codeCoverageIgnoreEnd
  705. }
  706.  
  707. /**
  708. * Validates a session_version=3 style session object.
  709. *
  710. * @param Array $session the session object
  711. * @return Array the session object if it validates, null otherwise
  712. */
  713. protected function validateSessionObject($session) {
  714. // make sure some essential fields exist
  715. if (is_array($session) &&
  716. isset($session['uid']) &&
  717. isset($session['access_token']) &&
  718. isset($session['sig'])) {
  719. // validate the signature
  720. $session_without_sig = $session;
  721. unset($session_without_sig['sig']);
  722. $expected_sig = self::generateSignature(
  723. $session_without_sig,
  724. $this->getApiSecret()
  725. );
  726. if ($session['sig'] != $expected_sig) {
  727. self::errorLog('Got invalid session signature in cookie.');
  728. $session = null;
  729. }
  730. // check expiry time
  731. } else {
  732. $session = null;
  733. }
  734. return $session;
  735. }
  736.  
  737. /**
  738. * Returns something that looks like our JS session object from the
  739. * signed token's data
  740. *
  741. * TODO: Nuke this once the login flow uses OAuth2
  742. *
  743. * @param Array the output of getSignedRequest
  744. * @return Array Something that will work as a session
  745. */
  746. protected function createSessionFromSignedRequest($data) {
  747. if (!isset($data['oauth_token'])) {
  748. return null;
  749. }
  750.  
  751. $session = array(
  752. 'uid' => $data['user_id'],
  753. 'access_token' => $data['oauth_token'],
  754. 'expires' => $data['expires'],
  755. );
  756.  
  757. // put a real sig, so that validateSignature works
  758. $session['sig'] = self::generateSignature(
  759. $session,
  760. $this->getApiSecret()
  761. );
  762.  
  763. return $session;
  764. }
  765.  
  766. /**
  767. * Parses a signed_request and validates the signature.
  768. * Then saves it in $this->signed_data
  769. *
  770. * @param String A signed token
  771. * @param Boolean Should we remove the parts of the payload that
  772. * are used by the algorithm?
  773. * @return Array the payload inside it or null if the sig is wrong
  774. */
  775. protected function parseSignedRequest($signed_request) {
  776. list($encoded_sig, $payload) = explode('.', $signed_request, 2);
  777.  
  778. // decode the data
  779. $sig = self::base64UrlDecode($encoded_sig);
  780. $data = json_decode(self::base64UrlDecode($payload), true);
  781.  
  782. if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
  783. self::errorLog('Unknown algorithm. Expected HMAC-SHA256');
  784. return null;
  785. }
  786.  
  787. // check sig
  788. $expected_sig = hash_hmac('sha256', $payload,
  789. $this->getApiSecret(), $raw = true);
  790. if ($sig !== $expected_sig) {
  791. self::errorLog('Bad Signed JSON signature!');
  792. return null;
  793. }
  794.  
  795. return $data;
  796. }
  797.  
  798. /**
  799. * Build the URL for api given parameters.
  800. *
  801. * @param $method String the method name.
  802. * @return String the URL for the given parameters
  803. */
  804. protected function getApiUrl($method) {
  805. static $READ_ONLY_CALLS =
  806. array('admin.getallocation' => 1,
  807. 'admin.getappproperties' => 1,
  808. 'admin.getbannedusers' => 1,
  809. 'admin.getlivestreamvialink' => 1,
  810. 'admin.getmetrics' => 1,
  811. 'admin.getrestrictioninfo' => 1,
  812. 'application.getpublicinfo' => 1,
  813. 'auth.getapppublickey' => 1,
  814. 'auth.getsession' => 1,
  815. 'auth.getsignedpublicsessiondata' => 1,
  816. 'comments.get' => 1,
  817. 'connect.getunconnectedfriendscount' => 1,
  818. 'dashboard.getactivity' => 1,
  819. 'dashboard.getcount' => 1,
  820. 'dashboard.getglobalnews' => 1,
  821. 'dashboard.getnews' => 1,
  822. 'dashboard.multigetcount' => 1,
  823. 'dashboard.multigetnews' => 1,
  824. 'data.getcookies' => 1,
  825. 'events.get' => 1,
  826. 'events.getmembers' => 1,
  827. 'fbml.getcustomtags' => 1,
  828. 'feed.getappfriendstories' => 1,
  829. 'feed.getregisteredtemplatebundlebyid' => 1,
  830. 'feed.getregisteredtemplatebundles' => 1,
  831. 'fql.multiquery' => 1,
  832. 'fql.query' => 1,
  833. 'friends.arefriends' => 1,
  834. 'friends.get' => 1,
  835. 'friends.getappusers' => 1,
  836. 'friends.getlists' => 1,
  837. 'friends.getmutualfriends' => 1,
  838. 'gifts.get' => 1,
  839. 'groups.get' => 1,
  840. 'groups.getmembers' => 1,
  841. 'intl.gettranslations' => 1,
  842. 'links.get' => 1,
  843. 'notes.get' => 1,
  844. 'notifications.get' => 1,
  845. 'pages.getinfo' => 1,
  846. 'pages.isadmin' => 1,
  847. 'pages.isappadded' => 1,
  848. 'pages.isfan' => 1,
  849. 'permissions.checkavailableapiaccess' => 1,
  850. 'permissions.checkgrantedapiaccess' => 1,
  851. 'photos.get' => 1,
  852. 'photos.getalbums' => 1,
  853. 'photos.gettags' => 1,
  854. 'profile.getinfo' => 1,
  855. 'profile.getinfooptions' => 1,
  856. 'stream.get' => 1,
  857. 'stream.getcomments' => 1,
  858. 'stream.getfilters' => 1,
  859. 'users.getinfo' => 1,
  860. 'users.getloggedinuser' => 1,
  861. 'users.getstandardinfo' => 1,
  862. 'users.hasapppermission' => 1,
  863. 'users.isappuser' => 1,
  864. 'users.isverified' => 1,
  865. 'video.getuploadlimits' => 1);
  866. $name = 'api';
  867. if (isset($READ_ONLY_CALLS[strtolower($method)])) {
  868. $name = 'api_read';
  869. } else if (strtolower($method) == 'video.upload') {
  870. $name = 'api_video';
  871. }
  872. return self::getUrl($name, 'restserver.php');
  873. }
  874.  
  875. /**
  876. * Build the URL for given domain alias, path and parameters.
  877. *
  878. * @param $name String the name of the domain
  879. * @param $path String optional path (without a leading slash)
  880. * @param $params Array optional query parameters
  881. * @return String the URL for the given parameters
  882. */
  883. protected function getUrl($name, $path='', $params=array()) {
  884. $url = self::$DOMAIN_MAP[$name];
  885. if ($path) {
  886. if ($path[0] === '/') {
  887. $path = substr($path, 1);
  888. }
  889. $url .= $path;
  890. }
  891. if ($params) {
  892. $url .= '?' . http_build_query($params, null, '&');
  893. }
  894. return $url;
  895. }
  896.  
  897. /**
  898. * Returns the Current URL, stripping it of known FB parameters that should
  899. * not persist.
  900. *
  901. * @return String the current URL
  902. */
  903. protected function getCurrentUrl() {
  904. $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on'
  905. ? 'https://'
  906. : 'http://';
  907. $currentUrl = $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
  908. $parts = parse_url($currentUrl);
  909.  
  910. // drop known fb params
  911. $query = '';
  912. if (!empty($parts['query'])) {
  913. $params = array();
  914. parse_str($parts['query'], $params);
  915. foreach(self::$DROP_QUERY_PARAMS as $key) {
  916. unset($params[$key]);
  917. }
  918. if (!empty($params)) {
  919. $query = '?' . http_build_query($params, null, '&');
  920. }
  921. }
  922.  
  923. // use port if non default
  924. $port =
  925. isset($parts['port']) &&
  926. (($protocol === 'http://' && $parts['port'] !== 80) ||
  927. ($protocol === 'https://' && $parts['port'] !== 443))
  928. ? ':' . $parts['port'] : '';
  929.  
  930. // rebuild
  931. return $protocol . $parts['host'] . $port . $parts['path'] . $query;
  932. }
  933.  
  934. /**
  935. * Generate a signature for the given params and secret.
  936. *
  937. * @param Array $params the parameters to sign
  938. * @param String $secret the secret to sign with
  939. * @return String the generated signature
  940. */
  941. protected static function generateSignature($params, $secret) {
  942. // work with sorted data
  943. ksort($params);
  944.  
  945. // generate the base string
  946. $base_string = '';
  947. foreach($params as $key => $value) {
  948. $base_string .= $key . '=' . $value;
  949. }
  950. $base_string .= $secret;
  951.  
  952. return md5($base_string);
  953. }
  954.  
  955. /**
  956. * Prints to the error log if you aren't in command line mode.
  957. *
  958. * @param String log message
  959. */
  960. protected static function errorLog($msg) {
  961. // disable error log if we are running in a CLI environment
  962. // @codeCoverageIgnoreStart
  963. if (php_sapi_name() != 'cli') {
  964. error_log($msg);
  965. }
  966. // uncomment this if you want to see the errors on the page
  967. // print 'error_log: '.$msg."\n";
  968. // @codeCoverageIgnoreEnd
  969. }
  970.  
  971. /**
  972. * Base64 encoding that doesn't need to be urlencode()ed.
  973. * Exactly the same as base64_encode except it uses
  974. * - instead of +
  975. * _ instead of /
  976. *
  977. * @param String base64UrlEncodeded string
  978. */
  979. protected static function base64UrlDecode($input) {
  980. return base64_decode(strtr($input, '-_', '+/'));
  981. }
  982. }
Add Comment
Please, Sign In to add comment