This week only. Pastebin PRO Accounts Christmas Special! Don't miss out!Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Feb 26th, 2012  |  syntax: None  |  size: 20.88 KB  |  views: 16  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  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.3';
  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($_REQUEST['session'])
  273.             : $_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] = $params;
  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. }
clone this paste RAW Paste Data