WordPress.org

Plugin Directory

Changeset 511514


Ignore:
Timestamp:
02/28/12 03:22:48 (2 years ago)
Author:
chriswallace
Message:

Fixed OAuth login to Facebook and WordPress user account auto-creation for WordPress 3.3.1.

Location:
wp-facebook-plugin/trunk
Files:
3 added
5 edited

Legend:

Unmodified
Added
Removed
  • wp-facebook-plugin/trunk/facebook.php

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

    r505995 r511514  
    4848        /* Our variables from the widget settings. */ 
    4949        $title = apply_filters('widget_title', $instance['title'] ); 
    50          
    51         if(is_single() || is_page()): 
    52              
    53             global $post; 
    54             $uid = get_the_permalink(); 
    55              
    56         else: 
    57  
    58             $uid = $instance['uid']; 
    59  
    60         endif; 
    6150 
    6251        $numposts = $instance['numposts']; 
     
    7362                 
    7463        $fbml = "<fb:comments "; 
     64         
     65        $fbml .= 'data-href="' . get_permalink() . '" '; 
    7566 
    7667        /* If number of comments was set, set limit. */ 
  • wp-facebook-plugin/trunk/widgets/fb-recommendations-widget.php

    r505995 r511514  
    186186} 
    187187 
    188         $instance['domain'] = strip_tags( $new_instance['domain'] ); 
    189         $instance['width'] = strip_tags( $new_instance['width'] ); 
    190         $instance['height'] = strip_tags( $new_instance['height'] ); 
    191         $instance['header'] = $new_instance['header']; 
    192         $instance['font'] = $new_instance['font']; 
    193         $instance['border_color'] = strip_tags( $new_instance['border_color'] ); 
    194  
    195188function show_fb_recommendations($atts){ 
    196189 
  • wp-facebook-plugin/trunk/wp-facebook.php

    r506041 r511514  
    33Plugin Name: WP Facebook 
    44Description: Allow users to create an account and sign in to your site with Facebook, adds your posts/pages to the Facebook Open Graph, and makes the new Facebook Social Plugins easy to use in widget form. 
    5 Version: 0.3.6 
     5Version: 0.4.2 
    66Author: UpThemes 
    7 Author URI: http://upthemes.com/ 
     7Plugin URI: http://upthemes.com/plugins/wp-facebook/ 
     8Author URI: http://upthemes.com 
    89*/ 
     10 
     11/** 
     12 * Returns current plugin version. 
     13 * 
     14 * @return string Plugin version 
     15 */ 
     16function plugin_get_version() { 
     17    if ( ! function_exists( 'get_plugins' ) ) 
     18        require_once( ABSPATH . 'wp-admin/includes/plugin.php' ); 
     19    $plugin_folder = get_plugins( '/' . plugin_basename( dirname( __FILE__ ) ) ); 
     20    $plugin_file = basename( ( __FILE__ ) ); 
     21    return $plugin_folder[$plugin_file]['Version']; 
     22} 
    923 
    1024/** 
     
    1327load_plugin_textdomain( 'wpfb', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' ); 
    1428 
    15 $root = dirname(dirname(dirname(dirname(__FILE__)))); 
    16 require_once($root . '/wp-includes/registration.php'); 
    17  
    1829define('FBOAUTH_APP_ID', 'fbOauth_app_id'); 
    1930define('FBOAUTH_APP_SECRET', 'fbOauth_app_secret'); 
     31define('WPFB_VERSION', plugin_get_version()); 
    2032 
    2133fbOauth_init(); 
     
    2335function fbOauth_init() { 
    2436     
    25     add_theme_support('post-thumbnails'); 
     37  add_theme_support('post-thumbnails'); 
    2638     
    2739  /** 
     
    4254      return; 
    4355  } 
    44  
     56   
    4557  /** 
    4658   * Gimme those widgets! 
     
    5567 
    5668  /** 
    57    * Add the xmlns:fb namespace to the page.  This is necessary  necessary for 
    58    *   xfbml to work in IE. 
     69   * Add the xmlns:fb namespace to the page.  This is necessary for 
     70   * xfbml to work in IE. 
    5971   */ 
    6072  add_filter('language_attributes', 'fbOauth_language_attributes'); 
     
    6577  add_action('wp_head', 'fbOauth_header'); 
    6678  add_action('login_head', 'fbOauth_header'); 
    67   add_action('login_head','check_login_form'); 
    6879 
    6980  /** 
     
    8798   * Init the plugin for users 
    8899   */ 
    89   add_action('init', 'fbOauth_init_auth', 20); 
     100  add_action('after_setup_theme', 'fbOauth_init_auth', 1); 
    90101         
    91102    /** 
    92103     * Determine whether to use/add Facebook commenting to posts 
    93104     */ 
    94          
    95     add_action('init','wpfb_comments'); 
    96  
     105  add_action('init','wpfb_comments'); 
     106 
     107  /** 
     108   * Load the jQuery!! 
     109   */ 
     110  add_action('init','wpfb_start_jquery'); 
     111 
     112    /** 
     113        * Load login styles for Facebook button 
     114        */ 
     115    add_action('login_head','wpfb_login_styles'); 
     116 
     117} 
     118 
     119function wpfb_start_jquery(){ 
     120 
     121    wp_enqueue_script('jquery'); 
     122 
     123} 
     124 
     125function wpfb_login_styles(){ 
     126     
     127    wp_enqueue_style('wpfb-login-styles', plugins_url( 'styles/wp-login.css', __FILE__ ), false, WPFB_VERSION ); 
     128     
    97129} 
    98130 
    99131function wpfb_not_configured_message(){ 
    100132 
    101     fbOauth_message(__("WP Facebook has been activated and <a href='options-general.php?page=wp-facebook/wp-facebook.php'>needs to be configured</a> in order to work properly.",'wpfb')); 
     133    fbOauth_message(__("WP Facebook has been activated and <a href='options-general.php?page=" . plugin_basename(dirname(__FILE__)) . "/wp-facebook.php'>needs to be configured</a> in order to work properly.",'wpfb')); 
    102134 
    103135} 
    104136 
    105137function fbOauth_admin_menu() { 
    106     if (!function_exists('add_options_page')) { 
     138    if (!function_exists('add_options_page')) 
    107139        return; 
    108     } 
    109  
    110     add_options_page('WP-Facebook', 
    111                      'WP-Facebook', 
    112                      8, 
     140 
     141    $wpfb = add_options_page('WP Facebook', 
     142                     'WP Facebook', 
     143                     'manage_options', 
    113144                     __FILE__, 
    114145                     'fbOauth_admin_options'); 
    115 } 
    116  
    117 function admin_styles(){ 
    118  
    119     if(is_admin() && $_REQUEST['page'] == 'wp-facebook/wp-facebook.php'){ 
    120         wp_enqueue_style('wpfb-admin',get_bloginfo('wpurl') . '/wp-content/plugins/wp-facebook/styles/wpfb-admin.css');  
    121     } 
    122  
    123 } 
    124  
    125 if($_REQUEST['page'] == 'wp-facebook/wp-facebook.php') 
    126   add_action('init','admin_styles'); 
    127  
     146 
     147    add_action( 'admin_print_styles-' . $wpfb, 'wpfb_admin_styles'); 
     148 
     149} 
     150 
     151function wpfb_admin_styles(){ 
     152    wp_enqueue_style('wpfb-admin', plugins_url( 'styles/wpfb-admin.css', __FILE__ ), false, WPFB_VERSION );  
     153} 
    128154 
    129155function fbOauth_admin_options() { 
     
    199225</form>'; 
    200226 
    201 echo '<div id="buy-themes"><h2>' . __('Buy a WordPress Theme from UpThemes','wpfb') . '</h2><iframe src="http://upthemes.com/buy-themes/" frameborder="0"></iframe></div>'; 
     227echo '<div class="credits"><h2>' . __('Brought to you by the folks at <a href="http://upthemes.com">UpThemes</a>','wpfb') . '</div>'; 
    202228 
    203229} 
     
    253279    require_once 'facebook.php'; 
    254280 
    255     global $fbOauth_facebook, $facebook_session; 
     281    global $fbOauth_facebook; 
    256282 
    257283    $fbOauth_facebook = new Facebook(array( 
     
    260286        'cookie' => true)); 
    261287 
    262     $facebook_session = $fbOauth_facebook->getSession(); 
    263  
    264     if ($facebook_session) { 
    265         try { 
    266             $user = $fbOauth_facebook->api('/me'); 
    267             fbOauth_sync_auth(); 
    268             add_action('comment_post', 'fbOauth_comment_post'); 
    269         } catch (Exception $e) { 
    270             $fbOauth_facebook->setSession(); 
    271             $facebook_session = null; 
    272         } 
    273     } 
     288    $user = wpfb_user_logged_in(); 
     289 
     290    if ( isset( $user ) ) { 
     291        // proceed knowing you have a logged in user who's authenticated 
     292        try { 
     293            $user = $fbOauth_facebook->api('/me'); 
     294            fbOauth_sync_auth(); 
     295            add_action('comment_post', 'fbOauth_comment_post'); 
     296        } catch (Exception $e) { 
     297            $fbOauth_facebook->destroySession(); 
     298        } 
     299     
     300    } 
    274301 
    275302    fbOauth_init_javascript_sdk(); 
     
    280307function fbOauth_init_javascript_sdk() { 
    281308     
    282     global $facebook_session; 
    283  
    284     $app_id     = get_option(FBOAUTH_APP_ID); 
    285          
    286     if(FB_LOGIN_FORM==true) 
    287         $location = '"' . get_bloginfo('wpurl') . '"'; 
     309    $user = wpfb_user_logged_in(); 
     310    
     311    $app_id = get_option( FBOAUTH_APP_ID ); 
     312    $redirect = wp_logout_url( get_bloginfo('url') ); 
     313    $wpurl = get_bloginfo('url'); 
     314    $channel_url = plugins_url('channel.php',__FILE__); 
     315    $fb_logout_redirect = $wpurl . $_SERVER['REQUEST_URI']; 
     316 
     317    if( in_array( $GLOBALS['pagenow'], array( 'wp-login.php', 'wp-register.php' ) ) && !$user ) 
     318        $location = '"' . get_bloginfo('url') . '"'; 
    288319    else 
    289         $location = window.location; 
     320        $location = "document.location"; 
    290321 
    291322    $fb_login = <<<EOF 
     
    295326EOF; 
    296327 
    297     $redirect = wp_logout_url( get_bloginfo('wpurl') ); 
    298  
    299     $wpurl = get_bloginfo('wpurl'); 
    300      
    301     $fb_logout_redirect = $wpurl . $_SERVER['REQUEST_URI']; 
    302  
    303328  $fb_logout = <<<EOF 
    304     jQuery("a[href*=logout]").live("click",function(e){ 
     329    jQuery('a[href*="logout"]').live("click",function(e){ 
     330         
    305331        e.preventDefault(); 
    306      
     332 
    307333        FB.logout(function(response) { 
    308334            if(response.success) 
    309                 window.location = '$fb_logout_redirect'; 
     335                window.location = $(this).attr('href'); 
     336            else 
     337                window.location = window.location; 
    310338        }); 
    311339     
     
    313341EOF; 
    314342 
    315     if($facebook_session && is_user_logged_in()) 
     343    if( $user && is_user_logged_in() ) 
    316344        $fb_login = $fb_logout; 
    317345     
    318346    $data = <<<EOF 
    319347<div id="fb-root"></div> 
    320 <script src="http://connect.facebook.net/en_US/all.js"></script> 
    321348<script> 
    322   FB.init({appId: '{$app_id}', status: true, cookie: true, xfbml: true}); 
    323   {$fb_login}   
     349window.fbAsyncInit = function() { 
     350    FB.init({ 
     351        appId       : '{$app_id}', 
     352        channelUrl  : '{$channel_url}', 
     353        status      : true, 
     354        cookie      : true, 
     355        xfbml       : true 
     356    }); 
     357    {$fb_login}   
     358    // Additional initialization code here 
     359}; 
    324360</script> 
     361<script> 
     362// Load the SDK Asynchronously 
     363(function(d){ 
     364   var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0]; 
     365   if (d.getElementById(id)) {return;} 
     366   js = d.createElement('script'); js.id = id; js.async = true; 
     367   js.src = "//connect.facebook.net/en_US/all.js"; 
     368   ref.parentNode.insertBefore(js, ref); 
     369 }(document)); 
     370 </script> 
    325371EOF; 
    326372 
    327373    _fbOauth_footer_register($data, true); 
     374 
    328375} 
    329376 
     
    343390    elseif(is_front_page() || is_home() || is_page()): 
    344391        $type = 'blog'; 
     392    else: 
     393        $type = 'page'; 
    345394    endif; 
    346395     
     
    355404    <?php endif; ?> 
    356405     
    357     <?php if(is_single() || is_page() || is_category() || is_tag() || is_archive() || is_attachment): ?> 
     406    <?php if( is_single() || is_page() || is_category() || is_tag() || is_archive() || is_attachment() ): ?> 
    358407        <meta property="og:url" content="<?php the_permalink() ?>"/> 
    359408        <?php if(has_post_thumbnail($post->ID)): ?> 
     
    394443 
    395444function fbOauth_login_button() { 
    396     global $facebook_session; 
    397  
    398     if (!$facebook_session && !is_user_logged_in()) { 
    399         echo "<fb:login-button perms='email,publish_stream'></fb:login-button>"; 
    400     } 
    401 } 
     445 
     446    $user = wpfb_user_logged_in(); 
     447     
     448    if (!$user && !is_user_logged_in()) { 
     449        echo '<div class="fb-login-button" data-show-faces="false" data-width="200" data-max-rows="1"  scope="email,publish_stream"></div>'; 
     450    } 
     451} 
     452 
     453add_action('init','fbOauth_sync_auth'); 
    402454 
    403455function fbOauth_sync_auth() { 
    404     global $fbOauth_facebook; 
    405  
     456     
    406457    try { 
    407         $fbuid = $fbOauth_facebook->getUser(); 
     458        $fbuid = wpfb_user_logged_in(); 
    408459    } catch (Exception $e) {} 
    409460 
    410461    $assoc_fbuid = 0; 
    411462    $user = wp_get_current_user(); 
     463 
    412464    if ( 0 != $user->ID ) { 
    413         $assoc_fbuid = get_usermeta($user->ID, 'fbuid'); 
    414     } 
    415  
     465        $assoc_fbuid = get_user_meta($user->ID, 'fbuid',true); 
     466    } 
     467     
    416468    if ($assoc_fbuid) { 
    417469        if ($fbuid == $assoc_fbuid) { 
     
    419471            return; 
    420472        } else { 
    421             //wp session, no fbsession = logout of wp and reload page 
    422             // or, user is logged in under a different fb account 
     473            //wp session, no fbsession = logout of wp and reload page or, user is logged in under a different fb account 
    423474            wp_logout(); 
    424475            header('Location: ' . $_SERVER['REQUEST_URI']); 
     
    426477        } 
    427478    } else { 
     479 
    428480        if ($user->ID) { 
    429481            // wpuser not associated w/ fb.  do nothing 
     
    445497 
    446498function fbOauth_login($allow_link=false) { 
    447     global $fbOauth_facebook; 
    448499 
    449500    try { 
    450         $fbuid = $fbOauth_facebook->getUser(); 
     501        $fbuid = wpfb_user_logged_in(); 
    451502    } catch (Exception $e) {} 
    452503 
     
    494545 
    495546    try { 
    496         $fbuid = $fbOauth_facebook->getUser(); 
     547        $fbuid = wpfb_user_logged_in(); 
    497548        $userinfo = $fbOauth_facebook->api('/me'); 
    498549    } catch (Exception $e) { 
     
    531582} 
    532583 
     584function wpfb_user_logged_in(){ 
     585 
     586    global $fbOauth_facebook; 
     587 
     588    $user = $fbOauth_facebook->getUser(); 
     589 
     590    if( !isset($user) || !$user ) 
     591        return; 
     592     
     593    return $user; 
     594         
     595} 
     596 
    533597function fb_post_this_field(){ 
    534  
    535     global $facebook_session; 
    536      
    537     if($facebook_session): 
     598     
     599    if( wpfb_user_logged_in() ): 
    538600        echo '<fieldset class="fb_post_this"><input id="fb_post_this" name="fb_post_this" type="checkbox"/> <label for="fb_post_this">' . __('Post comment to Facebook?','wpfb') . '</label></fieldset>'; 
    539601    endif; 
     
    569631} 
    570632 
    571 function check_login_form(){ 
    572     define('FB_LOGIN_FORM',true);    
    573 } 
    574  
    575633function wpfb_comments(){ 
    576634     
     
    584642    elseif($comment_option == 'add_comments'): 
    585643         
    586         add_action('comment_template','wpfb_comments_template'); 
     644        add_action('comments_template','wpfb_comments_template'); 
    587645 
    588646    endif; 
     
    596654     
    597655    update_option( "wpfb_comment_template_file", $file ); 
    598     return dirname( __FILE__ ) . '/wpfb-comment-template.php'; 
     656 
     657    $comments_template_path = dirname(__FILE__) . '/wpfb-comment-template.php'; 
     658     
     659    if( file_exists( dirname(__FILE__) . '/wpfb-comment-template.php') ) 
     660        return $comments_template_path; 
     661    else 
     662        return $file; 
     663 
    599664} 
    600665 
  • wp-facebook-plugin/trunk/wpfb-comment-template.php

    r505995 r511514  
    1515    <h3><?php _e('Facebook Comments','wpfb'); ?></h3> 
    1616 
    17     <fb:comments id="<?php echo get_the_ID() ?>" numposts="<?php if($numposts) echo $numposts; else echo '10'; ?>" width="<?php if($width) echo $width; else echo '500'; ?>" /> 
     17    <fb:comments id="<?php echo get_the_ID() ?>" data-href="<?php the_permalink(); ?>" numposts="<?php if($numposts) echo $numposts; else echo '10'; ?>" width="<?php if($width) echo $width; else echo '500'; ?>" /> 
    1818 
    1919</div> 
Note: See TracChangeset for help on using the changeset viewer.