Changeset 591316
- Timestamp:
- 08/28/2012 01:30:12 PM (14 years ago)
- Location:
- wp-meetup-activity/trunk
- Files:
-
- 1 added
- 4 edited
-
facebook-sdk/base_facebook.php (modified) (36 diffs)
-
facebook-sdk/class-facebook-wp.php (added)
-
facebook-sdk/facebook.php (modified) (3 diffs)
-
readme.txt (modified) (4 diffs)
-
wp-meetup-activity.php (modified) (16 diffs)
Legend:
- Unmodified
- Added
- Removed
-
wp-meetup-activity/trunk/facebook-sdk/base_facebook.php
r589801 r591316 16 16 */ 17 17 18 if (!function_exists('curl_init')) { 19 throw new Exception('Facebook needs the CURL PHP extension.'); 20 } 21 if (!function_exists('json_decode')) { 22 throw new Exception('Facebook needs the JSON PHP extension.'); 23 } 24 18 if ( ! class_exists( 'WP_FacebookApiException' ) ): 25 19 /** 26 20 * Thrown when an API call returns an exception. … … 28 22 * @author Naitik Shah <naitik@facebook.com> 29 23 */ 30 class FacebookApiException extends Exception24 class WP_FacebookApiException extends Exception 31 25 { 32 26 /** … … 43 37 $this->result = $result; 44 38 45 $code = isset($result['error_code']) ? $result['error_code'] : 0; 39 //when api call fails (no available transport, i.e. cURL etc. not working), error code comes 40 // out as string 'http_failure', but $code needs to be int. is_int returns false if !isset() 41 $code = is_int($result['error_code']) ? $result['error_code'] : 0; 46 42 47 43 if (isset($result['error_description'])) { … … 106 102 } 107 103 } 108 104 endif; 105 106 if ( ! class_exists( 'WP_BaseFacebook' ) ): 109 107 /** 110 108 * Provides access to the Facebook Platform. This class provides … … 116 114 * @author Naitik Shah <naitik@facebook.com> 117 115 */ 118 abstract class BaseFacebook116 abstract class WP_BaseFacebook 119 117 { 120 118 /** 121 119 * Version. 122 120 */ 123 const VERSION = '3.2.0'; 124 125 /** 126 * Signed Request Algorithm. 127 */ 128 const SIGNED_REQUEST_ALGORITHM = 'HMAC-SHA256'; 129 130 /** 131 * Default options for curl. 132 */ 133 public static $CURL_OPTS = array( 134 CURLOPT_CONNECTTIMEOUT => 10, 135 CURLOPT_RETURNTRANSFER => true, 136 CURLOPT_TIMEOUT => 60, 137 CURLOPT_USERAGENT => 'facebook-php-3.2', 138 ); 121 const VERSION = '3.1.1'; 139 122 140 123 /** … … 152 135 */ 153 136 public static $DOMAIN_MAP = array( 154 'api' => 'https://api.facebook.com/',155 'api_video' => 'https://api-video.facebook.com/',156 'api_read' => 'https://api-read.facebook.com/',157 'graph' => 'https://graph.facebook.com/',137 'api' => 'https://api.facebook.com/', 138 'api_video' => 'https://api-video.facebook.com/', 139 'api_read' => 'https://api-read.facebook.com/', 140 'graph' => 'https://graph.facebook.com/', 158 141 'graph_video' => 'https://graph-video.facebook.com/', 159 'www' => 'https://www.facebook.com/',142 'www' => 'https://www.facebook.com/', 160 143 ); 161 144 … … 205 188 */ 206 189 protected $fileUploadSupport = false; 207 208 /**209 * Indicates if we trust HTTP_X_FORWARDED_* headers.210 *211 * @var boolean212 */213 protected $trustForwarded = false;214 190 215 191 /** … … 229 205 $this->setFileUploadSupport($config['fileUpload']); 230 206 } 231 if (isset($config['trustForwarded']) && $config['trustForwarded']) { 232 $this->trustForwarded = true; 233 } 207 234 208 $state = $this->getPersistentData('state'); 235 209 if (!empty($state)) { 236 $this->state = $ state;210 $this->state = $this->getPersistentData('state'); 237 211 } 238 212 } … … 242 216 * 243 217 * @param string $appId The Application ID 244 * @return BaseFacebook218 * @return WP_BaseFacebook 245 219 */ 246 220 public function setAppId($appId) { … … 262 236 * 263 237 * @param string $apiSecret The App Secret 264 * @return BaseFacebook238 * @return WP_BaseFacebook 265 239 * @deprecated 266 240 */ … … 274 248 * 275 249 * @param string $appSecret The App Secret 276 * @return BaseFacebook250 * @return WP_BaseFacebook 277 251 */ 278 252 public function setAppSecret($appSecret) { … … 299 273 return $this->appSecret; 300 274 } 301 302 /** 303 * Set the file upload support status. 304 * 305 * @param boolean $fileUploadSupport The file upload support status. 306 * @return BaseFacebook 307 */ 308 public function setFileUploadSupport($fileUploadSupport) { 309 $this->fileUploadSupport = $fileUploadSupport; 310 return $this; 311 } 312 313 /** 314 * Get the file upload support status. 315 * 316 * @return boolean true if and only if the server supports file upload. 317 */ 318 public function getFileUploadSupport() { 319 return $this->fileUploadSupport; 320 } 321 322 /** 323 * DEPRECATED! Please use getFileUploadSupport instead. 324 * 325 * Get the file upload support status. 326 * 327 * @return boolean true if and only if the server supports file upload. 328 */ 329 public function useFileUploadSupport() { 330 return $this->getFileUploadSupport(); 331 } 332 333 /** 334 * Sets the access token for api calls. Use this if you get 335 * your access token by other means and just want the SDK 336 * to use it. 337 * 338 * @param string $access_token an access token. 339 * @return BaseFacebook 340 */ 341 public function setAccessToken($access_token) { 342 $this->accessToken = $access_token; 343 return $this; 344 } 345 346 /** 347 * Extend an access token, while removing the short-lived token that might 348 * have been generated via client-side flow. Thanks to http://bit.ly/b0Pt0H 349 * for the workaround. 275 276 /** 277 * Extend an access token, while removing the short-lived token that might have been generated via client-side flow. 278 * Thanks to http://stackoverflow.com/questions/486896/adding-a-parameter-to-the-url-with-javascript for the workaround 350 279 */ 351 280 public function setExtendedAccessToken() { … … 353 282 // need to circumvent json_decode by calling _oauthRequest 354 283 // directly, since response isn't JSON format. 355 $access_token_response = $this->_oauthRequest(356 $this-> getUrl('graph', '/oauth/access_token'),357 $params = array(358 'client_id' => $this->getAppId(),284 $access_token_response = 285 $this->_oauthRequest( 286 $this->getUrl('graph', '/oauth/access_token'), 287 $params = array( 'client_id' => $this->getAppId(), 359 288 'client_secret' => $this->getAppSecret(), 360 'grant_type' => 'fb_exchange_token', 361 'fb_exchange_token' => $this->getAccessToken(), 362 ) 363 ); 364 } 365 catch (FacebookApiException $e) { 366 // most likely that user very recently revoked authorization. 367 // In any event, we don't have an access token, so say so. 368 return false; 369 } 289 'grant_type'=>'fb_exchange_token', 290 'fb_exchange_token'=>$this->getAccessToken(), 291 )); 292 } catch (WP_FacebookApiException $e) { 293 // most likely that user very recently revoked authorization. 294 // In any event, we don't have an access token, so say so. 295 return false; 296 } 370 297 371 if (empty($access_token_response)) {372 return false;373 }298 if (empty($access_token_response)) { 299 return false; 300 } 374 301 375 $response_params = array(); 376 parse_str($access_token_response, $response_params); 377 378 if (!isset($response_params['access_token'])) { 379 return false; 380 } 381 382 $this->destroySession(); 383 384 $this->setPersistentData( 385 'access_token', $response_params['access_token'] 386 ); 302 $response_params = array(); 303 parse_str($access_token_response, $response_params); 304 305 if (!isset($response_params['access_token'])) { 306 return false; 307 } 308 309 $this->destroySession(); 310 311 $this->setPersistentData('access_token', $response_params['access_token']); 312 } 313 314 /** 315 * Set the file upload support status. 316 * 317 * @param boolean $fileUploadSupport The file upload support status. 318 * @return WP_BaseFacebook 319 */ 320 public function setFileUploadSupport($fileUploadSupport) { 321 $this->fileUploadSupport = $fileUploadSupport; 322 return $this; 323 } 324 325 /** 326 * Get the file upload support status. 327 * 328 * @return boolean true if and only if the server supports file upload. 329 */ 330 public function getFileUploadSupport() { 331 return $this->fileUploadSupport; 332 } 333 334 /** 335 * DEPRECATED! Please use getFileUploadSupport instead. 336 * 337 * Get the file upload support status. 338 * 339 * @return boolean true if and only if the server supports file upload. 340 */ 341 public function useFileUploadSupport() { 342 return $this->getFileUploadSupport(); 343 } 344 345 /** 346 * Sets the access token for api calls. Use this if you get 347 * your access token by other means and just want the SDK 348 * to use it. 349 * 350 * @param string $access_token an access token. 351 * @return WP_BaseFacebook 352 */ 353 public function setAccessToken($access_token) { 354 $this->accessToken = $access_token; 355 return $this; 387 356 } 388 357 … … 602 571 array_merge(array( 603 572 'next' => $this->getCurrentUrl(), 604 'access_token' => $this->get UserAccessToken(),573 'access_token' => $this->getAccessToken(), 605 574 ), $params) 606 575 ); … … 649 618 * Constructs and returns the name of the cookie that 650 619 * potentially houses the signed request for the app user. 651 * The cookie is not set by the BaseFacebook class, but620 * The cookie is not set by the WP_BaseFacebook class, but 652 621 * it may be set by the JavaScript SDK. 653 622 * … … 661 630 /** 662 631 * Constructs and returns the name of the coookie that potentially contain 663 * metadata. The cookie is not set by the BaseFacebook class, but it may be632 * metadata. The cookie is not set by the WP_BaseFacebook class, but it may be 664 633 * set by the JavaScript SDK. 665 634 * … … 711 680 $user_info = $this->api('/me'); 712 681 return $user_info['id']; 713 } catch ( FacebookApiException $e) {682 } catch (WP_FacebookApiException $e) { 714 683 return 0; 715 684 } … … 770 739 'redirect_uri' => $redirect_uri, 771 740 'code' => $code)); 772 } catch ( FacebookApiException $e) {741 } catch (WP_FacebookApiException $e) { 773 742 // most likely that user very recently revoked authorization. 774 743 // In any event, we don't have an access token, so say so. … … 795 764 * 796 765 * @return mixed The decoded response object 797 * @throws FacebookApiException766 * @throws WP_FacebookApiException 798 767 */ 799 768 protected function _restserver($params) { … … 810 779 if (is_array($result) && isset($result['error_code'])) { 811 780 $this->throwAPIException($result); 812 // @codeCoverageIgnoreStart 813 } 814 // @codeCoverageIgnoreEnd 815 816 $method = strtolower($params['method']); 817 if ($method === 'auth.expiresession' || 818 $method === 'auth.revokeauthorization') { 781 } 782 783 if ($params['method'] === 'auth.expireSession' || 784 $params['method'] === 'auth.revokeAuthorization') { 819 785 $this->destroySession(); 820 786 } … … 846 812 * 847 813 * @return mixed The decoded response object 848 * @throws FacebookApiException814 * @throws WP_FacebookApiException 849 815 */ 850 816 protected function _graph($path, $method = 'GET', $params = array()) { … … 869 835 if (is_array($result) && isset($result['error'])) { 870 836 $this->throwAPIException($result); 871 // @codeCoverageIgnoreStart 872 } 873 // @codeCoverageIgnoreEnd 837 } 874 838 875 839 return $result; … … 883 847 * 884 848 * @return string The decoded response object 885 * @throws FacebookApiException849 * @throws WP_FacebookApiException 886 850 */ 887 851 protected function _oauthRequest($url, $params) { … … 945 909 } 946 910 947 // With dual stacked DNS responses, it's possible for a server to948 // have IPv6 enabled but not have IPv6 connectivity. If this is949 // the case, curl will try IPv4 first and if that fails, then it will950 // fall back to IPv6 and the error EHOSTUNREACH is returned by the951 // operating system.952 if ($result === false && empty($opts[CURLOPT_IPRESOLVE])) {953 $matches = array();954 $regex = '/Failed to connect to ([^:].*): Network is unreachable/';955 if (preg_match($regex, curl_error($ch), $matches)) {956 if (strlen(@inet_pton($matches[1])) === 16) {957 self::errorLog('Invalid IPv6 configuration on server, '.958 'Please disable or get native IPv6 on your server.');959 self::$CURL_OPTS[CURLOPT_IPRESOLVE] = CURL_IPRESOLVE_V4;960 curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);961 $result = curl_exec($ch);962 }963 }964 }965 966 911 if ($result === false) { 967 $e = new FacebookApiException(array(912 $e = new WP_FacebookApiException(array( 968 913 'error_code' => curl_errno($ch), 969 914 'error' => array( … … 992 937 $data = json_decode(self::base64UrlDecode($payload), true); 993 938 994 if (strtoupper($data['algorithm']) !== self::SIGNED_REQUEST_ALGORITHM) { 995 self::errorLog( 996 'Unknown algorithm. Expected ' . self::SIGNED_REQUEST_ALGORITHM); 939 if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') { 940 self::errorLog('Unknown algorithm. Expected HMAC-SHA256'); 997 941 return null; 998 942 } … … 1007 951 1008 952 return $data; 1009 }1010 1011 /**1012 * Makes a signed_request blob using the given data.1013 *1014 * @param array The data array.1015 * @return string The signed request.1016 */1017 protected function makeSignedRequest($data) {1018 if (!is_array($data)) {1019 throw new InvalidArgumentException(1020 'makeSignedRequest expects an array. Got: ' . print_r($data, true));1021 }1022 $data['algorithm'] = self::SIGNED_REQUEST_ALGORITHM;1023 $data['issued_at'] = time();1024 $json = json_encode($data);1025 $b64 = self::base64UrlEncode($json);1026 $raw_sig = hash_hmac('sha256', $b64, $this->getAppSecret(), $raw = true);1027 $sig = self::base64UrlEncode($raw_sig);1028 return $sig.'.'.$b64;1029 953 } 1030 954 … … 1130 1054 } 1131 1055 1132 protected function getHttpHost() {1133 if ($this->trustForwarded && isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {1134 return $_SERVER['HTTP_X_FORWARDED_HOST'];1135 }1136 return $_SERVER['HTTP_HOST'];1137 }1138 1139 protected function getHttpProtocol() {1140 if ($this->trustForwarded && isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {1141 if ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {1142 return 'https';1143 }1144 return 'http';1145 }1146 if (isset($_SERVER['HTTPS']) &&1147 ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] == 1)) {1148 return 'https';1149 }1150 return 'http';1151 }1152 1153 /**1154 * Get the base domain used for the cookie.1155 */1156 protected function getBaseDomain() {1157 // The base domain is stored in the metadata cookie if not we fallback1158 // to the current hostname1159 $metadata = $this->getMetadataCookie();1160 if (array_key_exists('base_domain', $metadata) &&1161 !empty($metadata['base_domain'])) {1162 return trim($metadata['base_domain'], '.');1163 }1164 return $this->getHttpHost();1165 }1166 1167 /**1168 1169 1056 /** 1170 1057 * Returns the Current URL, stripping it of known FB parameters that should … … 1174 1061 */ 1175 1062 protected function getCurrentUrl() { 1176 $protocol = $this->getHttpProtocol() . '://'; 1177 $host = $this->getHttpHost(); 1178 $currentUrl = $protocol.$host.$_SERVER['REQUEST_URI']; 1063 if (isset($_SERVER['HTTPS']) && 1064 ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1) || 1065 isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && 1066 $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') { 1067 $protocol = 'https://'; 1068 } 1069 else { 1070 $protocol = 'http://'; 1071 } 1072 $currentUrl = $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; 1179 1073 $parts = parse_url($currentUrl); 1180 1074 … … 1236 1130 */ 1237 1131 protected function throwAPIException($result) { 1238 $e = new FacebookApiException($result);1132 $e = new WP_FacebookApiException($result); 1239 1133 switch ($e->getType()) { 1240 1134 // OAuth 2.0 Draft 00 style … … 1266 1160 // disable error log if we are running in a CLI environment 1267 1161 // @codeCoverageIgnoreStart 1268 if (php_sapi_name() != 'cli') {1269 error_log($msg);1270 }1162 // if (php_sapi_name() != 'cli') { 1163 //error_log($msg); 1164 // } 1271 1165 // uncomment this if you want to see the errors on the page 1272 1166 // print 'error_log: '.$msg."\n"; … … 1279 1173 * - instead of + 1280 1174 * _ instead of / 1281 * No padded =1282 1175 * 1283 1176 * @param string $input base64UrlEncoded string … … 1286 1179 protected static function base64UrlDecode($input) { 1287 1180 return base64_decode(strtr($input, '-_', '+/')); 1288 }1289 1290 /**1291 * Base64 encoding that doesn't need to be urlencode()ed.1292 * Exactly the same as base64_encode except it uses1293 * - instead of +1294 * _ instead of /1295 *1296 * @param string $input string1297 * @return string base64Url encoded string1298 */1299 protected static function base64UrlEncode($input) {1300 $str = strtr(base64_encode($input), '+/', '-_');1301 $str = str_replace('=', '', $str);1302 return $str;1303 1181 } 1304 1182 … … 1318 1196 unset($_COOKIE[$cookie_name]); 1319 1197 if (!headers_sent()) { 1320 $base_domain = $this->getBaseDomain(); 1321 setcookie($cookie_name, '', 1, '/', '.'.$base_domain); 1198 // The base domain is stored in the metadata cookie if not we fallback 1199 // to the current hostname 1200 $base_domain = '.'. $_SERVER['HTTP_HOST']; 1201 1202 $metadata = $this->getMetadataCookie(); 1203 if (array_key_exists('base_domain', $metadata) && 1204 !empty($metadata['base_domain'])) { 1205 $base_domain = $metadata['base_domain']; 1206 } 1207 1208 setcookie($cookie_name, '', 0, '/', $base_domain); 1322 1209 } else { 1323 // @codeCoverageIgnoreStart1324 1210 self::errorLog( 1325 1211 'There exists a cookie that we wanted to clear that we couldn\'t '. 1326 1212 'clear because headers was already sent. Make sure to do the first '. 1327 'API call before outputing anything .'1213 'API call before outputing anything' 1328 1214 ); 1329 // @codeCoverageIgnoreEnd1330 1215 } 1331 1216 } … … 1363 1248 } 1364 1249 1365 protected static function isAllowedDomain($big, $small) {1366 if ($big === $small) {1367 return true;1368 }1369 return self::endsWith($big, '.'.$small);1370 }1371 1372 protected static function endsWith($big, $small) {1373 $len = strlen($small);1374 if ($len === 0) {1375 return true;1376 }1377 return substr($big, -$len) === $small;1378 }1379 1380 1250 /** 1381 1251 * Each of the following four methods should be overridden in … … 1400 1270 1401 1271 /** 1402 * Get the data for $key, persisted by BaseFacebook::setPersistentData()1272 * Get the data for $key, persisted by WP_BaseFacebook::setPersistentData() 1403 1273 * 1404 1274 * @param string $key The key of the data to retrieve … … 1424 1294 abstract protected function clearAllPersistentData(); 1425 1295 } 1296 endif; -
wp-meetup-activity/trunk/facebook-sdk/facebook.php
r589801 r591316 16 16 */ 17 17 18 require_once "base_facebook.php"; 18 require_once( dirname(__FILE__) . '/base_facebook.php' ); 19 20 if ( ! class_exists( 'WP_Facebook' ) ): 19 21 20 22 /** 21 * Extends the BaseFacebook class with the intent of using23 * Extends the WP_BaseFacebook class with the intent of using 22 24 * PHP sessions to store user ids and access tokens. 23 25 */ 24 class Facebook extendsBaseFacebook26 class WP_Facebook extends WP_BaseFacebook 25 27 { 26 const FBSS_COOKIE_NAME = 'fbss';27 28 // We can set this to a high number because the main session29 // expiration will trump this.30 const FBSS_COOKIE_EXPIRE = 31556926; // 1 year31 32 // Stores the shared session ID if one is set.33 protected $sharedSessionID;34 35 28 /** 36 29 * Identical to the parent constructor, except that … … 39 32 * we discover them. 40 33 * 41 * @param Array $config the application configuration. Additionally 42 * accepts "sharedSession" as a boolean to turn on a secondary 43 * cookie for environments with a shared session (that is, your app 44 * shares the domain with other apps). 45 * @see BaseFacebook::__construct in facebook.php 34 * @param Array $config the application configuration. 35 * @see WP_BaseFacebook::__construct in facebook.php 46 36 */ 47 37 public function __construct($config) { 48 if (!session_id()) { 49 session_start(); 50 } 38 51 39 parent::__construct($config); 52 if (!empty($config['sharedSession'])) {53 $this->initSharedSession();54 }55 40 } 56 41 57 42 protected static $kSupportedKeys = 58 43 array('state', 'code', 'access_token', 'user_id'); 59 60 protected function initSharedSession() {61 $cookie_name = $this->getSharedSessionCookieName();62 if (isset($_COOKIE[$cookie_name])) {63 $data = $this->parseSignedRequest($_COOKIE[$cookie_name]);64 if ($data && !empty($data['domain']) &&65 self::isAllowedDomain($this->getHttpHost(), $data['domain'])) {66 // good case67 $this->sharedSessionID = $data['id'];68 return;69 }70 // ignoring potentially unreachable data71 }72 // evil/corrupt/missing case73 $base_domain = $this->getBaseDomain();74 $this->sharedSessionID = md5(uniqid(mt_rand(), true));75 $cookie_value = $this->makeSignedRequest(76 array(77 'domain' => $base_domain,78 'id' => $this->sharedSessionID,79 )80 );81 $_COOKIE[$cookie_name] = $cookie_value;82 if (!headers_sent()) {83 $expire = time() + self::FBSS_COOKIE_EXPIRE;84 setcookie($cookie_name, $cookie_value, $expire, '/', '.'.$base_domain);85 } else {86 // @codeCoverageIgnoreStart87 self::errorLog(88 'Shared session ID cookie could not be set! You must ensure you '.89 'create the Facebook instance before headers have been sent. This '.90 'will cause authentication issues after the first request.'91 );92 // @codeCoverageIgnoreEnd93 }94 }95 44 96 45 /** … … 135 84 $this->clearPersistentData($key); 136 85 } 137 if ($this->sharedSessionID) {138 $this->deleteSharedSessionCookie();139 }140 }141 142 protected function deleteSharedSessionCookie() {143 $cookie_name = $this->getSharedSessionCookieName();144 unset($_COOKIE[$cookie_name]);145 $base_domain = $this->getBaseDomain();146 setcookie($cookie_name, '', 1, '/', '.'.$base_domain);147 }148 149 protected function getSharedSessionCookieName() {150 return self::FBSS_COOKIE_NAME . '_' . $this->getAppId();151 86 } 152 87 153 88 protected function constructSessionVariableName($key) { 154 $parts = array('fb', $this->getAppId(), $key); 155 if ($this->sharedSessionID) { 156 array_unshift($parts, $this->sharedSessionID); 157 } 158 return implode('_', $parts); 89 return implode('_', array('fb', 90 $this->getAppId(), 91 $key)); 159 92 } 160 93 } 94 endif; -
wp-meetup-activity/trunk/readme.txt
r589800 r591316 2 2 Contributors: o-zone 3 3 Donate link: http://www.zerozone.it 4 Tags: meetup, activity, meetup.com, group 4 Tags: meetup, activity, meetup.com, group, facebook 5 5 Requires at least: 3.0 6 6 Tested up to: 3.4.1 … … 8 8 License URI: http://www.gnu.org/licenses/gpl-2.0.html 9 9 10 WP-Meetup-Activity display your groups latest activities (discussions, photos...) in a sidebar widget 10 WP-Meetup-Activity display your groups latest activities (discussions, photos...) in a sidebar widget. Can also post directly to facebook pages new threads and replies 11 11 12 12 == Description == … … 22 22 2. Activate the plugin through the 'Plugins' menu in WordPress 23 23 3. Add the widget wherever you want 24 25 if you want to enable facebook Post-to-page feature, you need to create a new app: 26 27 1. Open your browser to https://developers.facebook.com/apps 28 2. Click on "Create new application" on top right 29 3. Set domain URLs 30 4. Write app Id and app secret on wp-meetup-activity setup page 31 5. Connect widget with your Facebook application, allowing manage_pages and offline_access rights 24 32 25 33 == Frequently Asked Questions == … … 40 48 41 49 = 0.1.2 = 42 * 50 * Facebook support for Post-in-Page on new topics / reply 51 * Minor bugs fixed 43 52 44 53 = 0.1.1 = -
wp-meetup-activity/trunk/wp-meetup-activity.php
r589800 r591316 28 28 29 29 /* Facebook PHP SDK */ 30 require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'facebook-sdk/facebook.php'); 30 if(!class_exists( 'Facebook_WP' )) { 31 require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'facebook-sdk/class-facebook-wp.php'); 32 } 31 33 32 34 add_option('wpmeetupactivity_apikey', '', '', 'yes'); … … 137 139 138 140 $apikey = get_option('wpmeetupactivity_apikey'); 141 142 $fb_options = get_option('wpmeetupactivity_fb_options'); 143 $fb_pages = $fb_options['pages']; 139 144 140 145 $groupsArray = get_option('wpmeetupactivity_groups'); … … 190 195 191 196 $wpdb->query($wpdb->prepare("UPDATE ".WP_MEETUP_ACTIVITY_TABLE."_act SET message_id=%d,author=%s,ranking=%f,item_type=%s,chg_date=NOW() WHERE group_id=$groupId AND thread_id=$threadId;",$messageId,$act['member_name'],$ranking,$act['item_type'])); 197 198 if($fb_options['post_on_reply']) { 199 /* Post replies to FB pages, if configured */ 200 wpmeetupactivity_fb_posttopage($act['link'],$act['discussion_body']); 201 } 202 203 if(is_admin()) { 204 echo "<div class=\"updated\"><p><strong>".__('Updated thread '.$act['discussion_title'], $wpmeetupactivity_textdomain)."</strong></p></div>"; 205 } 192 206 } 193 207 } else { 194 208 /* Add new thread row - Ranking: 1 */ 195 209 $wpdb->query($wpdb->prepare("INSERT INTO ".WP_MEETUP_ACTIVITY_TABLE."_act (group_id, thread_id, message_id, author, item_type, item_title, item_url, ranking, chg_date, add_date) VALUES ( %d, %d, %d, %s, %s, %s, %s, 1, NOW(), NOW())", $groupId, $threadId, $messageId, $act['member_name'], $act['item_type'], $act['discussion_title'], $act['link'])); 210 211 if($fb_options['post_on_new']) { 212 /* Post new threads to FB pages, if configured */ 213 wpmeetupactivity_fb_posttopage($act['link'],$act['discussion_body']); 214 } 215 216 if(is_admin()) { 217 echo "<div class=\"updated\"><p><strong>".__('Added new thread '.$act['discussion_title'], $wpmeetupactivity_textdomain)."</strong></p></div>"; 218 } 196 219 } 197 220 } … … 252 275 253 276 $groupsArray = get_option('wpmeetupactivity_groups'); 254 $myPrefs = get_option('wpmeetupactivity_prefs'); 255 256 $orderBy = $myPrefs['orderBy']; 277 $my_prefs = get_option('wpmeetupactivity_prefs'); 278 279 $fb_options = get_option('wpmeetupactivity_fb_options'); 280 $fb_pages = $fb_options['pages']; 281 282 $orderBy = $my_prefs['orderBy']; 257 283 if(empty($orderBy)) { 258 284 $orderBy = 'add_date'; … … 289 315 290 316 echo "<a href='".$act["item_url"]."'"; 291 if($my Prefs["openInNewWindow"]) {317 if($my_prefs["openInNewWindow"]) { 292 318 echo " target='_new'"; 293 319 } 294 320 echo ">$title</a>"; 295 if($my Prefs["displayAuthor"]) {321 if($my_prefs["displayAuthor"]) { 296 322 echo " by ".$act["author"]; 297 323 } 298 if($my Prefs["displayDate"]) {324 if($my_prefs["displayDate"]) { 299 325 echo " on ".$act["add_date"]; 300 326 } … … 302 328 303 329 $disp_cnt = $disp_cnt+1; 304 if($disp_cnt > $my Prefs["displayAct"]) {330 if($disp_cnt > $my_prefs["displayAct"]) { 305 331 break; 306 332 } … … 351 377 */ 352 378 353 354 function wpmeetupactivity_fb_posttopage($message,$title,$link,$tags,$description='') { 379 function wpmeetupactivity_fb_get_locale() { 380 $fb_valid_fb_locales = array( 381 'ca_ES', 'cs_CZ', 'cy_GB', 'da_DK', 'de_DE', 'eu_ES', 'en_PI', 'en_UD', 'ck_US', 'en_US', 'es_LA', 'es_CL', 'es_CO', 'es_ES', 'es_MX', 382 'es_VE', 'fb_FI', 'fi_FI', 'fr_FR', 'gl_ES', 'hu_HU', 'it_IT', 'ja_JP', 'ko_KR', 'nb_NO', 'nn_NO', 'nl_NL', 'pl_PL', 'pt_BR', 'pt_PT', 383 'ro_RO', 'ru_RU', 'sk_SK', 'sl_SI', 'sv_SE', 'th_TH', 'tr_TR', 'ku_TR', 'zh_CN', 'zh_HK', 'zh_TW', 'fb_LT', 'af_ZA', 'sq_AL', 'hy_AM', 384 'az_AZ', 'be_BY', 'bn_IN', 'bs_BA', 'bg_BG', 'hr_HR', 'nl_BE', 'en_GB', 'eo_EO', 'et_EE', 'fo_FO', 'fr_CA', 'ka_GE', 'el_GR', 'gu_IN', 385 'hi_IN', 'is_IS', 'id_ID', 'ga_IE', 'jv_ID', 'kn_IN', 'kk_KZ', 'la_VA', 'lv_LV', 'li_NL', 'lt_LT', 'mk_MK', 'mg_MG', 'ms_MY', 'mt_MT', 386 'mr_IN', 'mn_MN', 'ne_NP', 'pa_IN', 'rm_CH', 'sa_IN', 'sr_RS', 'so_SO', 'sw_KE', 'tl_PH', 'ta_IN', 'tt_RU', 'te_IN', 'ml_IN', 'uk_UA', 387 'uz_UZ', 'vi_VN', 'xh_ZA', 'zu_ZA', 'km_KH', 'tg_TJ', 'ar_AR', 'he_IL', 'ur_PK', 'fa_IR', 'sy_SY', 'yi_DE', 'gn_PY', 'qu_PE', 'ay_BO', 388 'se_NO', 'ps_AF', 'tl_ST' 389 ); 390 391 $locale = get_locale(); 392 393 // convert locales like "es" to "es_ES", in case that works for the given locale (sometimes it does) 394 if (strlen($locale) == 2) { 395 $locale = strtolower($locale).'_'.strtoupper($locale); 396 } 397 398 // convert things like de-DE to de_DE 399 $locale = str_replace('-', '_', $locale); 400 401 // check to see if the locale is a valid FB one, if not, use en_US as a fallback 402 if ( !in_array($locale, $fb_valid_fb_locales) ) { 403 $locale = 'en_US'; 404 } 405 406 return apply_filters('fb_locale', $locale); // filter the locale in case somebody has a weird case and needs to change it 407 } 408 409 function wpmeetupactivity_fb_js_sdk_setup() { 410 $options = get_option( 'fb_options' ); 411 412 if ( empty( $options['app_id'] ) ) 413 return; 414 415 $args = apply_filters( 'fb_init', array( 416 'appId' => $options['app_id'], 417 'channelUrl' => add_query_arg( 'fb-channel-file', 1, site_url( '/' ) ), 418 'status' => true, 419 'cookie' => true, 420 'xfbml' => true, 421 'oauth' => true 422 ) ); 423 424 echo '<script type="text/javascript">window.fbAsyncInit=function(){FB.init(' . json_encode( $args ) . ');'; 425 do_action( 'fb_async_init', $args ); 426 echo '}</script>'; 427 428 $locale = wpmeetupactivity_fb_get_locale(); 429 if ( ! $locale ) 430 return; 431 wp_enqueue_script( 'fb-connect', ( is_ssl() ? 'https' : 'http' ) . '://connect.facebook.net/' . $locale . '/all.js', array(), null, true ); 432 433 add_action( 'wp_footer', 'wpmeetupactivity_fb_root' ); 434 } 435 436 function wpmeetupactivity_fb_root() { 437 echo '<div id="fb-root"></div>'; 438 } 439 440 441 function wpmeetupactivity_fb_posttopage($link,$message) { 355 442 global $facebook; 356 443 357 $options = get_option('wpmeetupactivity_fb_options'); 358 359 444 $fb_options = get_option('wpmeetupactivity_fb_options'); 445 446 if(count($fb_options['pages']) > 0) { 447 foreach($fb_options['pages'] as $fb_page_id) { 448 $args = array( 449 // 'access_token' => $facebook->getAccessToken(), 450 'from' => $fb_page_id, 451 'link' => $link, 452 'message' => $message, 453 ); 454 455 try { 456 $publish_result = $facebook->api("/$fb_page_id/feed", 'POST', $args); 457 } catch (WP_FacebookApiException $e) { 458 $error_result = $e->getResult(); 459 if(is_admin()) { 460 echo "<div class=\"error\"><p><strong>".__('FB Post-to-Page error: '.$error_result, $wpmeetupactivity_textdomain)."</strong></p></div>"; 461 } 462 } 463 464 print_r($publish_result); 465 } 466 } 360 467 } 361 468 … … 369 476 if ( ! isset( $facebook ) ) 370 477 return $accounts; 371 372 $facebook->setAccessToken($options['access_token']);373 478 374 479 try { 375 480 $accounts = $facebook->api('/me/accounts', 'GET', array('ref' => 'fbwpp')); 376 481 } catch (FacebookApiException $e) { 377 echo $e;378 482 return $accounts; 379 483 } … … 389 493 390 494 // appId and secret are required by BaseFacebook 391 if ( ( ! empty( $options['app_id'] ) && ! empty( $options['app_secret'] ) ) ) { 392 $facebook = new Facebook(array( 393 'appId' => $options['app_id'], 394 'secret' => $options['app_secret'], 395 )); 396 397 $options['access_token'] = $facebook->getAccessToken(); 398 399 update_option('wpmeetupactivity_fb_options',$options); 400 } 495 if((!empty( $options['app_id']) && !empty($options['app_secret']))) { 496 $facebook = new Facebook_WP_Extend(array( 497 'appId' => $options['app_id'], 498 'secret' => $options['app_secret'], 499 )); 500 } 501 502 add_action( 'wp_head', 'wpmeetupactivity_fb_js_sdk_setup' ); 503 add_action( 'admin_head', 'wpmeetupactivity_fb_js_sdk_setup' ); 401 504 } 402 505 … … 414 517 $myGroups = array(); 415 518 416 $my Prefs = get_option('wpmeetupactivity_prefs');417 if(!is_array($my Prefs)) {418 $my Prefs = array();519 $my_prefs = get_option('wpmeetupactivity_prefs'); 520 if(!is_array($my_prefs)) { 521 $my_prefs = array(); 419 522 } 420 523 … … 428 531 429 532 if($_POST["wpmeetupactivity_prefs_opennewwindows"] == 'on') { 430 $my Prefs["openInNewWindow"] = true;533 $my_prefs["openInNewWindow"] = true; 431 534 } else { 432 $my Prefs["openInNewWindow"] = false;535 $my_prefs["openInNewWindow"] = false; 433 536 } 434 537 435 538 436 539 if($_POST["wpmeetupactivity_prefs_displayauthor"] == 'on') { 437 $my Prefs["displayAuthor"] = true;540 $my_prefs["displayAuthor"] = true; 438 541 } else { 439 $my Prefs["displayAuthor"] = false;542 $my_prefs["displayAuthor"] = false; 440 543 } 441 544 442 545 if($_POST["wpmeetupactivity_prefs_displaydate"] == 'on') { 443 $my Prefs["displayDate"] = true;546 $my_prefs["displayDate"] = true; 444 547 } else { 445 $my Prefs["displayDate"] = false;548 $my_prefs["displayDate"] = false; 446 549 } 447 550 448 $my Prefs["displayAct"] = intval($_POST["wpmeetupactivity_prefs_displayact"]);449 $my Prefs["orderBy"] = intval($_POST["wpmeetupactivity_prefs_orderby"]);551 $my_prefs["displayAct"] = intval($_POST["wpmeetupactivity_prefs_displayact"]); 552 $my_prefs["orderBy"] = intval($_POST["wpmeetupactivity_prefs_orderby"]); 450 553 451 554 // Salva opzioni … … 453 556 update_option('wpmeetupactivity_title',$_POST['wpmeetupactivity_title']); 454 557 update_option('wpmeetupactivity_groups',$myGroups); 455 update_option('wpmeetupactivity_prefs',$my Prefs);558 update_option('wpmeetupactivity_prefs',$my_prefs); 456 559 457 560 // FB options … … 460 563 $fb_options['app_secret'] = $_POST['wpmeetupactivity_fb_appsecret']; 461 564 565 if($_POST["wpmeetupactivity_fb_post_on_new"] == 'on') { 566 $fb_options['post_on_new'] = true; 567 } else { 568 $fb_options['post_on_new'] = false; 569 } 570 571 if($_POST["wpmeetupactivity_fb_post_on_reply"] == 'on') { 572 $fb_options['post_on_reply'] = true; 573 } else { 574 $fb_options['post_on_reply'] = false; 575 } 576 577 $fb_pages = array(); 578 579 foreach($_POST["wpmeetupactivity_fb_pages"] as $pageId => $val) { 580 $fb_pages[] = $pageId; 581 } 582 583 $fb_options['pages'] = $fb_pages; 584 462 585 update_option('wpmeetupactivity_fb_options',$fb_options); 463 586 … … 538 661 </p> 539 662 <p> 540 <input type='checkbox' name='wpmeetupactivity_prefs_opennewwindows' ".wpmeetupactivity_is_checked($my Prefs["openInNewWindow"])."> Open link in a new window663 <input type='checkbox' name='wpmeetupactivity_prefs_opennewwindows' ".wpmeetupactivity_is_checked($my_prefs["openInNewWindow"])."> Open link in a new window 541 664 </p> 542 665 <p> 543 <input type='checkbox' name='wpmeetupactivity_prefs_displayauthor' ".wpmeetupactivity_is_checked($my Prefs["displayAuthor"])."> Display post author name666 <input type='checkbox' name='wpmeetupactivity_prefs_displayauthor' ".wpmeetupactivity_is_checked($my_prefs["displayAuthor"])."> Display post author name 544 667 </p> 545 668 <p> 546 <input type='checkbox' name='wpmeetupactivity_prefs_displaydate' ".wpmeetupactivity_is_checked($my Prefs["displayDate"])."> Display post date669 <input type='checkbox' name='wpmeetupactivity_prefs_displaydate' ".wpmeetupactivity_is_checked($my_prefs["displayDate"])."> Display post date 547 670 </p> 548 671 <p> 549 672 Max number of activities to show: <select name='wpmeetupactivity_prefs_displayact'> 550 <option value=2 ".wpmeetupactivity_is_selected($my Prefs["displayAct"],2).">2</option>551 <option value=5 ".wpmeetupactivity_is_selected($my Prefs["displayAct"],5).">5</option>552 <option value=10 ".wpmeetupactivity_is_selected($my Prefs["displayAct"],10).">10</option>553 <option value=15 ".wpmeetupactivity_is_selected($my Prefs["displayAct"],15).">15</option>554 <option value=20 ".wpmeetupactivity_is_selected($my Prefs["displayAct"],20).">20</option>673 <option value=2 ".wpmeetupactivity_is_selected($my_prefs["displayAct"],2).">2</option> 674 <option value=5 ".wpmeetupactivity_is_selected($my_prefs["displayAct"],5).">5</option> 675 <option value=10 ".wpmeetupactivity_is_selected($my_prefs["displayAct"],10).">10</option> 676 <option value=15 ".wpmeetupactivity_is_selected($my_prefs["displayAct"],15).">15</option> 677 <option value=20 ".wpmeetupactivity_is_selected($my_prefs["displayAct"],20).">20</option> 555 678 </select> 556 679 </p> 557 680 <p> 558 681 Order activities by: <select name='wpmeetupactivity_prefs_orderby'> 559 <option value='add_date' ".wpmeetupactivity_is_selected($my Prefs["orderBy"],'add_date').">Add date</option>560 <option value='chg_date' ".wpmeetupactivity_is_selected($my Prefs["orderBy"],'chg_date').">Change date</option>561 <option value='ranking' ".wpmeetupactivity_is_selected($my Prefs["orderBy"],'ranking').">Ranking</option>682 <option value='add_date' ".wpmeetupactivity_is_selected($my_prefs["orderBy"],'add_date').">Add date</option> 683 <option value='chg_date' ".wpmeetupactivity_is_selected($my_prefs["orderBy"],'chg_date').">Change date</option> 684 <option value='ranking' ".wpmeetupactivity_is_selected($my_prefs["orderBy"],'ranking').">Ranking</option> 562 685 </select> 563 686 </p> … … 568 691 569 692 echo "<fieldset class='wpmeetupactivity-setup-fieldset'><legend> Facebook settings </legend>"; 693 694 $fb_user = $facebook->getUser(); 570 695 571 696 if ((empty($fb_options['app_id']) || empty($fb_options['app_secret'])) && current_user_can( 'manage_options' ) ) { … … 574 699 echo "</strong></p></div>"; 575 700 } else { 576 $user = $facebook->getUser(); 577 578 if ($user) { 579 try { 580 // Proceed knowing you have a logged in user who's authenticated. 581 echo "<b>User: ".$facebook->api('/me')."</b><br/>"; 582 } catch (FacebookApiException $e) { 583 echo $e; 701 $params = array( 'scope' => 'read_stream, manage_pages, publish_stream, offline_access' ); 702 if ($fb_user) { 703 // Proceed knowing you have a logged in user who's authenticated. 704 echo "<b>Currently connected as: $user</b> (<a href='".$facebook->getLogoutUrl()."'>Disconnect from Facebook</a>)<br/>"; 705 } else { 706 echo "Not connected (<a href='".$facebook->getLoginUrl($params)."'>Connect with Facebook App</a>)"; 707 } 708 } 709 echo "<p> 710 App Id: <input type='text' size='64' name='wpmeetupactivity_fb_appid' value='".$fb_options['app_id']."' /> 711 </p><p> 712 App Secret: <input type='text' size='128' name='wpmeetupactivity_fb_appsecret' value='".$fb_options['app_secret']."' /> 713 </p></fieldset>"; 714 if ($fb_user) { 715 echo "<fieldset class='wpmeetupactivity-setup-fieldset'><legend> Facebook Post-on-Page </legend> 716 <p> 717 <input type='checkbox' name='wpmeetupactivity_fb_post_on_new' ".wpmeetupactivity_is_checked($fb_options["post_on_new"])."> Post new threads on FB pages 718 </p><p> 719 <input type='checkbox' name='wpmeetupactivity_fb_post_on_reply' ".wpmeetupactivity_is_checked($my_prefs["post_on_reply"])."> Post every reply on FB pages (not suggested) 720 </p><p>"; 721 if(is_array($fb_options['pages'])) { 722 $fb_pages = $fb_options['pages']; 723 } else { 724 $fb_pages = array(); 725 } 726 727 $c=0; 728 729 foreach(wpmeetupactivity_fb_getuserpages() as $fb_page) { 730 $fb_page_id = $fb_page['id']; 731 if(is_array($fb_page['perms'])) { 732 if(in_array('CREATE_CONTENT',$fb_page['perms'])) { 733 echo "<input type='checkbox' name='wpmeetupactivity_fb_pages[".$fb_page_id."]' ".wpmeetupactivity_is_checked(in_array($fb_page_id,$fb_pages))."> ".$fb_page['name']." (<a href='http://www.facebook.com/$fb_page_id'>link</a>)<br/>"; 734 $c++; 735 } 584 736 } 585 } else { 586 $params = array( 'scope' => 'read_stream, friends_likes, publish_stream, offline_access' ); 587 echo "<a href='".$facebook->getLoginUrl($params)."'>Connect with Facebook App</a>"; 588 } 589 590 print_r(wpmeetupactivity_fb_getuserpages()); 591 } 592 echo " 593 <p> 594 App Id: <input type='text' size='64' name='wpmeetupactivity_fb_appid' value='".$fb_options['app_id']."' /> 595 </p> 596 <p> 597 App Secret: <input type='text' size='128' name='wpmeetupactivity_fb_appsecret' value='".$fb_options['app_secret']."' /> 598 </p> 599 <p> 600 Access Token is <b>".$fb_options['access_token']."</b> 601 </p> 602 </fieldset> 603 <p class='submit'><input type='submit' name='Submit' value='Save changes' /></p> 737 } 738 if($c == 0) { 739 echo "Sorry: you can't write to any page with this Facebook account !"; 740 } 741 echo "</p></fieldset>"; 742 } 743 echo "<p class='submit'><input type='submit' name='Submit' value='Save changes' /></p> 604 744 </form> 605 745 </div><!-- /WRAP -->"; 606 607 746 } 608 747
Note: See TracChangeset
for help on using the changeset viewer.