$value"; exit_wrapper (); } /** * @name saveoauthuserinfo */ function saveoauthuserinfo( $loginid='', $oauthuseremailaddress='', $oauthuserkey='', $oauthusersecret='', $oauthuserprovider='', $oauthuserproviderusername='', $oauthuserproviderref='', $oauthuserprovideravatarurl='' ){ if(empty($loginid) || empty($oauthuserkey) || empty($oauthuserprovider)){ return ''; } $oauthuser = getoauthuserinfo($loginid,$oauthuseremailaddress,$oauthuserprovider); if($oauthuser[oauthuserid]==''){ $sql = " INSERT INTO tbloauthuser ( oauthuserprovider, oauthuserkey, oauthusersecret, loginid, "; if($oauthuseremailaddress){ $sql .= " oauthuseremailaddress, "; } if($oauthuserprovideravatarurl){ $sql .= " oauthuserprovideravatarurl, "; } $sql .= " oauthuserproviderusername, oauthuserproviderref ) VALUES ( '$oauthuserprovider', '".addslashes($oauthuserkey)."', '".addslashes($oauthusersecret)."', '$loginid', "; if($oauthuseremailaddress){ $sql .= " '".addslashes($oauthuseremailaddress)."', "; } if($oauthuserprovideravatarurl){ $sql .= " '".addslashes($oauthuserprovideravatarurl)."', "; } $sql .= " '$oauthuserproviderusername', '$oauthuserproviderref' ) "; if(db_exec($sql)){ return true; } else{ return false; } } else{ $sql = " UPDATE tbloauthuser SET oauthuserkey='".addslashes($oauthuserkey)."', oauthusersecret='".addslashes($oauthusersecret)."' WHERE loginid='$loginid' AND oauthuserprovider='$oauthuserprovider' AND oauthuseremailaddress='".addslashes($oauthuseremailaddress)."' "; if(db_exec($sql)){ return true; } else{ return false; } } } /** * @name getoauthuserinfo * @param integer $loginid * @param string $oauthuseremailaddress * @param string $oauthuserprovider * @param integer $oauthuserid * @param integer $oauthuserproviderref * @return boolean */ function getoauthuserinfo($loginid='',$oauthuseremailaddress='',$oauthuserprovider='',$oauthuserid=0,$oauthuserproviderref=0){ $sql = " select * from tbloauthuser where 1=1 "; if($loginid){ $sql .= " AND loginid ='$loginid' "; } if($oauthuserid){ $sql .= " AND oauthuserid ='$oauthuserid' "; } if(is_array($oauthuserprovider)){ $oauthuserprovider_counter = 0; $sql .= " AND ("; foreach($oauthuserprovider as $key=>$provider){ if($oauthuserprovider_counter>0){ $sql .= " OR "; } $sql .= " oauthuserprovider ='$provider' "; $oauthuserprovider_counter++; } $sql .= ")"; }else if($$oauthuserprovider!=0){ $sql .= " AND oauthuserprovider ='$oauthuserprovider' "; } if($oauthuseremailaddress){ $sql .= " AND oauthuseremailaddress ='$oauthuseremailaddress' "; } if($oauthuserproviderref){ $sql .= " AND oauthuserproviderref ='$oauthuserproviderref' "; } $oauthuser = db_query($sql); d_dev('getoauthuserinfo', array('sql' => $sql, 'qry' => $oauthuser)); if(count($oauthuser)>0){ return $oauthuser; } else{ return false; } } ########### # Geneeric Social Posting Functions ########### /** * @name social_verify * @param integer $oauthuserid * @param integer $loginid * @return boolean */ function social_verify($oauthuserid,$loginid=0){ if(!is_numeric($oauthuserid)){ return "Invalid oauthuserid, must be numeric."; } $sql = "SELECT * FROM tbloauthuser WHERE oauthuserid = $oauthuserid "; if($loginid && is_numeric($loginid)){ $sql .= "AND loginid = $loginid "; } $sql .= " LIMIT 1 "; $oauth = db_query($sql); if(trim($oauth[0][oauthuserprovider])=="twitter"){ return twitter_verify($oauthuserid); } else if(trim($oauth[0][oauthuserprovider])=="facebook"){ return facebook_verify($oauthuserid); } else { return false; } } /** * @name social_verify_own * @param integer $oauthuserid * @param integer $loginid * @return boolean */ function social_verify_own($oauthuserid,$loginid=0){ if(!is_numeric($oauthuserid)){ return "Invalid oauthuserid, must be numeric."; } $sql = "SELECT * FROM tbloauthuser WHERE oauthuserid = $oauthuserid "; if($loginid && is_numeric($loginid)){ $sql .= "AND loginid = $loginid "; } $sql .= " LIMIT 1 "; //d(sql,$sql) $oauth = db_query($sql); //d($oauth); if($oauth[0][oauthuserid]==$oauthuserid){ return true; } else { return false; } } /** * @name social_update_avatar * @param integer $oauthuserid * @param string $url * @return boolean */ function social_update_avatar($oauthuserid='',$url){ if(!is_numeric($oauthuserid)){ return false; } $sql = " UPDATE tbloauthuser SET oauthuserprovideravatarurl='".addslashes($url)."' WHERE oauthuserid='$oauthuserid' "; if(db_exec($sql)){ return true; } else{ return false; } } /** * @name social_post * @param integer $oauthuserid * @param string $postmessage * @param integer $attachment * @return boolean */ function social_post($oauthuserid,$postmessage,$attachment=0){ if(!social_verify($oauthuserid)){ d(oathid,$oauthuserid); return false; } if(!is_numeric($oauthuserid)){ return "Invalid oauthuserid, must be numeric."; } $sql = "SELECT * FROM tbloauthuser WHERE oauthuserid = $oauthuserid LIMIT 1"; $oauth = db_first($sql); d(oauth,$oauth); d(msg,$postmessage); //exit; if(trim($oauth[oauthuserprovider])=="twitter"){ $twitterresult = twitter_post($oauthuserid,$postmessage); if($twitterresult){ return $twitterresult; } else { return false; } } else if(trim($oauth[oauthuserprovider])=="facebook"){ $facebookresult = facebook_post($oauthuserid,$postmessage,$attachment); if($facebookresult){ return $facebookresult; } else { return false; } } } /** * @name social_delete * @param integer $oauthuserid * @return boolean */ function social_delete($oauthuserid){ if(!is_numeric($oauthuserid)){ return "Invalid oauthuserid, must be numeric."; } $loginid= loginid(); if(!social_verify_own($oauthuserid,$loginid)){ return false; } $sql = "DELETE FROM tbloauthuser WHERE oauthuserid = $oauthuserid "; $deleteresult = db_query($sql); //d(deletesql,$sql); //d(deleteresult,$deleteresult); return true; } ########### # Twitter Start ########## /** * @name twitter_post * @param integer $oauthuserid * @param string $messagetopost * @return boolean */ function twitter_post($oauthuserid='',$messagetopost=''){ $oauth_accounts = getoauthuserinfo(0,0,0,$oauthuserid); d(oath_accnts,$oauth_accounts); if($oauth_accounts[0][oauthuserkey] && $oauth_accounts[0][oauthusersecret]){ //this is token and token secret for the USERS oauth authentication $token = trim($oauth_accounts[0][oauthuserkey]); $tokensecret = trim($oauth_accounts[0][oauthusersecret]); $twcon = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET,$token,$tokensecret); $content = $twcon->get('account/verify_credentials'); d(content,$content); d(msg,$messagetopost); $posted = $twcon->post('statuses/update', array('status' => $messagetopost)); //this is for debugging, if needed //$lastapicall = $twcon->lastAPICall(); d(posted,$posted); //exit; if($posted->id_str){ return $posted->id_str; } else { return false; } }else{ return false; } } /** * @name twitter_verify * @param integer $oauthuserid * @return boolean */ function twitter_verify($oauthuserid=''){ $oauth_accounts = getoauthuserinfo(0,0,0,$oauthuserid); if(trim($oauth_accounts[0][oauthuserprovider])!="twitter"){ return false; } if($oauth_accounts[0][oauthuserkey] && $oauth_accounts[0][oauthusersecret]){ //this is token and token secret for the USERS oauth authentication $token = trim($oauth_accounts[0][oauthuserkey]); $tokensecret = trim($oauth_accounts[0][oauthusersecret]); $twcon = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET,$token,$tokensecret ); $twittercred = $twcon->get('account/verify_credentials'); // d(twittercred,$twittercred); global $twitterdata; $twitterdata= (array) $twittercred; if($twittercred->id_str){ $twitter_avatar_url = $twittercred->profile_image_url_https; if($twitter_avatar_url){ social_update_avatar($oauthuserid,$twitter_avatar_url); } return true; } else { return false; } }else{ return false; } } /** * Method for creating a base string from an array and base URI. * @param string $twitter_baseURI the URI of the request to twitter * @param array $params the OAuth associative array * @return string the encoded base string **/ /** * @name twitter_buildBaseString * @param string $twitter_baseURI * @param array $params * @return boolean */ function twitter_buildBaseString($twitter_baseURI, $params){ $r = array(); //temporary array if(is_array($params)){ ksort($params); //sort params alphabetically by keys foreach($params as $key=>$value){ $r[] = "$key=" . rawurlencode($value); //create key=value strings }//end foreach } return "POST&" . rawurlencode($twitter_baseURI) . '&' . rawurlencode(implode('&', $r)); //return complete base string }//end twitter_buildBaseString() /** * Method for creating the composite key. * @param string $twitter_consumerSecret the consumer secret authorized by Twitter * @param string $requestToken the request token from Twitter * @return string the composite key. **/ /** * @name twitter_getCompositeKey * @param string $twitter_consumerSecret * @param string $requestToken * @return boolean */ function twitter_getCompositeKey($twitter_consumerSecret, $requestToken){ return rawurlencode($twitter_consumerSecret) . '&' . rawurlencode($requestToken); }//end getCompositeKey() /** * Method for building the OAuth header. * @param array $twitter_oauth the oauth array. * @return string the authorization header. **/ /** * @name twitter_buildAuthorizationHeader * @param string $twitter_oauth * @return boolean */ function twitter_buildAuthorizationHeader($twitter_oauth){ $r = 'Authorization: OAuth '; //header prefix $values = array(); //temporary key=value array foreach($twitter_oauth as $key=>$value) $values[] = "$key=\"" . rawurlencode($value) . "\""; //encode key=value string $r .= implode(', ', $values); //reassemble return $r; //return full authorization header }//end buildAuthorizationHeader() /** * Method for sending a request to Twitter. * @param array $twitter_oauth the oauth array * @param string $twitter_baseURI the request URI * @return string the response from Twitter **/ /** * @name twitter_sendRequest * @param string $twitter_oauth * @param string $twitter_baseURI * @return boolean */ function twitter_sendRequest($twitter_oauth, $twitter_baseURI) { if (!$twitter_baseURI) $twitter_baseURI="https://riogenesis.com/desktop.php"; $header = array( twitter_buildAuthorizationHeader($twitter_oauth), 'Expect:'); //create header array and add 'Expect:' $options = array(CURLOPT_HTTPHEADER => $header, //use our authorization and expect header CURLOPT_HEADER => false, //don't retrieve the header back from Twitter CURLOPT_URL => $twitter_baseURI, //the URI we're sending the request to CURLOPT_POST => true, //this is going to be a POST - required CURLOPT_RETURNTRANSFER => true, //return content as a string, don't echo out directly CURLOPT_SSL_VERIFYPEER => false, //don't verify SSL certificate, just do it CURLOPT_SSL_VERIFYHOST => false, CURLOPT_CONNECTTIMEOUT =>10); // Set connection timeout to 10 sec. $ch = curl_init(); //get a channel curl_setopt_array($ch, $options); //set options $response = curl_exec($ch); //make the call curl_close($ch); //hang up return $response; }//end sendRequest() //get request token $twitter_baseURI = 'https://api.twitter.com/oauth/request_token'; $twitter_accesTokenURI = 'https://api.twitter.com/oauth/access_token'; $twitter_authorizeURI = 'https://api.twitter.com/oauth/authorize'; $twitter_nonce = time(); $twitter_timestamp = time(); $twitter_consumerSecret = 'VAS1Q6g0t8PURzOaKTO0s1hkSk8MFHqUCdSIw8VF4'; //put your actual consumer secret here, it will look something like 'MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98' if($_GET[setupoauth_twitter]=="1"){ $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET); $temporary_credentials = $connection->getRequestToken(); /* Request access tokens from twitter */ $_SESSION[twitter]=$temporary_credentials; $redirect_url = $connection->getAuthorizeURL($temporary_credentials); header('Location: '.$redirect_url); } else if($_GET[setupoauth_twitter]=="2"){ $twitter_oauth = array( 'oauth_callback' => 'http://' . $_SERVER['HTTP_HOST'].'/accountsettings.php?tab=socialsetup&twittercallback1=1', 'oauth_token' => $_GET['oauth_token'], 'oauth_verifier' => $_GET['oauth_verifier'], 'oauth_nonce' => $twitter_nonce, 'oauth_signature_method' => 'HMAC-SHA1', 'oauth_timestamp' => $twitter_timestamp, 'oauth_version' => '1.0' ); $twitter_baseStringAccess = twitter_buildBaseString($twitter_accesTokenURI, $oauth); $twitter_compositeKey = twitter_getCompositeKey($consumerSecret, $_GET['oauth_token']); $twitter_oauth_signature = base64_encode(hash_hmac('sha1', $twitter_baseStringAccess , $twitter_compositeKey, true)); //sign the base string $twitter_oauth['oauth_signature'] = $twitter_oauth_signature; $twitter_response = twitter_sendRequest($twitter_oauth, $twitter_accesTokenURI); //getting the access tokens � up to this point it works great $twitter_responseArray = array(); $twitter_parts = explode('&', $twitter_response); foreach($twitter_parts as $p){ $p = explode('=', $p); $twitter_responseArray[$p[0]] = $p[1]; } echo $response; echo "
";
	print_r($twitter_responseArray);
	echo "
"; } ########### # Twitter End ########## ####################################################### # TwitterOauth Start ######################################## /** * Twitter OAuth class */ class TwitterOAuth { /* Contains the last HTTP status code returned. */ public $http_code; /* Contains the last API call. */ public $url; /* Set up the API root URL. */ public $host = "https://api.twitter.com/1.1/"; /* Set timeout default. */ public $timeout = 30; /* Set connect timeout. */ public $connecttimeout = 30; /* Verify SSL Cert. */ public $ssl_verifypeer = FALSE; /* Respons format. */ public $format = 'json'; /* Decode returned json data. */ public $decode_json = TRUE; /* Contains the last HTTP headers returned. */ public $http_info; /* Set the useragnet. */ public $useragent = 'TwitterOAuth v0.2.0-beta2'; /* Immediately retry the API call if the response was not successful. */ //public $retry = TRUE; /** * Set API URLS */ function accessTokenURL() { return 'https://api.twitter.com/oauth/access_token'; } function authenticateURL() { return 'https://twitter.com/oauth/authenticate'; } function authorizeURL() { return 'https://twitter.com/oauth/authorize'; } function requestTokenURL() { return 'https://api.twitter.com/oauth/request_token'; } /** * Debug helpers */ function lastStatusCode() { return $this->http_status; } function lastAPICall() { return $this->last_api_call; } /** * construct TwitterOAuth object */ function __construct($consumer_key, $consumer_secret, $oauth_token = NULL, $oauth_token_secret = NULL) { $this->sha1_method = new OAuthSignatureMethod_HMAC_SHA1(); $this->consumer = new OAuthConsumer($consumer_key, $consumer_secret); if (!empty($oauth_token) && !empty($oauth_token_secret)) { $this->token = new OAuthConsumer($oauth_token, $oauth_token_secret); } else { $this->token = NULL; } } /** * Get a request_token from Twitter * * @returns a key/value array containing oauth_token and oauth_token_secret */ function getRequestToken($oauth_callback = NULL) { $parameters = array(); if (!empty($oauth_callback)) { $parameters['oauth_callback'] = $oauth_callback; } $request = $this->oAuthRequest($this->requestTokenURL(), 'GET', $parameters); $token = OAuthUtil::parse_parameters($request); $this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']); return $token; } /** * Get the authorize URL * * @returns a string */ function getAuthorizeURL($token, $sign_in_with_twitter = TRUE) { if (is_array($token)) { $token = $token['oauth_token']; } if (empty($sign_in_with_twitter)) { return $this->authorizeURL() . "?oauth_token={$token}"; } else { return $this->authenticateURL() . "?oauth_token={$token}"; } } /** * Exchange request token and secret for an access token and * secret, to sign API calls. * * @returns array("oauth_token" => "the-access-token", * "oauth_token_secret" => "the-access-secret", * "user_id" => "9436992", * "screen_name" => "abraham") */ function getAccessToken($oauth_verifier = FALSE) { $parameters = array(); if (!empty($oauth_verifier)) { $parameters['oauth_verifier'] = $oauth_verifier; } $request = $this->oAuthRequest($this->accessTokenURL(), 'GET', $parameters); $token = OAuthUtil::parse_parameters($request); $this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']); return $token; } /** * One time exchange of username and password for access token and secret. * * @returns array("oauth_token" => "the-access-token", * "oauth_token_secret" => "the-access-secret", * "user_id" => "9436992", * "screen_name" => "abraham", * "x_auth_expires" => "0") */ function getXAuthToken($username, $password) { $parameters = array(); $parameters['x_auth_username'] = $username; $parameters['x_auth_password'] = $password; $parameters['x_auth_mode'] = 'client_auth'; $request = $this->oAuthRequest($this->accessTokenURL(), 'POST', $parameters); $token = OAuthUtil::parse_parameters($request); $this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']); return $token; } /** * GET wrapper for oAuthRequest. */ function get($url, $parameters = array()) { $response = $this->oAuthRequest($url, 'GET', $parameters); if ($this->format === 'json' && $this->decode_json) { return json_decode($response); } return $response; } /** * POST wrapper for oAuthRequest. */ function post($url, $parameters = array()) { $response = $this->oAuthRequest($url, 'POST', $parameters); if ($this->format === 'json' && $this->decode_json) { return json_decode($response); } return $response; } /** * DELETE wrapper for oAuthReqeust. */ function delete($url, $parameters = array()) { $response = $this->oAuthRequest($url, 'DELETE', $parameters); if ($this->format === 'json' && $this->decode_json) { return json_decode($response); } return $response; } /** * Format and sign an OAuth / API request */ function oAuthRequest($url, $method, $parameters) { if (strrpos($url, 'https://') !== 0 && strrpos($url, 'http://') !== 0) { $url = "{$this->host}{$url}.{$this->format}"; } $request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, $method, $url, $parameters); $request->sign_request($this->sha1_method, $this->consumer, $this->token); switch ($method) { case 'GET': return $this->http($request->to_url(), 'GET'); default: return $this->http($request->get_normalized_http_url(), $method, $request->to_postdata()); } } /** * Make an HTTP request * * @return API results */ function http($url, $method, $postfields = NULL) { $this->http_info = array(); $ci = curl_init(); /* Curl settings */ curl_setopt($ci, CURLOPT_USERAGENT, $this->useragent); curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, $this->connecttimeout); curl_setopt($ci, CURLOPT_TIMEOUT, $this->timeout); curl_setopt($ci, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ci, CURLOPT_HTTPHEADER, array('Expect:')); curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, $this->ssl_verifypeer); curl_setopt($ci, CURLOPT_HEADERFUNCTION, array($this, 'getHeader')); curl_setopt($ci, CURLOPT_HEADER, FALSE); switch ($method) { case 'POST': curl_setopt($ci, CURLOPT_POST, TRUE); if (!empty($postfields)) { curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields); } break; case 'DELETE': curl_setopt($ci, CURLOPT_CUSTOMREQUEST, 'DELETE'); if (!empty($postfields)) { $url = "{$url}?{$postfields}"; } } curl_setopt($ci, CURLOPT_URL, $url); $response = curl_exec($ci); $this->http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE); $this->http_info = array_merge($this->http_info, curl_getinfo($ci)); $this->url = $url; curl_close ($ci); return $response; } /** * Get the header info to store. */ function getHeader($ch, $header) { $i = strpos($header, ':'); if (!empty($i)) { $key = str_replace('-', '_', strtolower(substr($header, 0, $i))); $value = trim(substr($header, $i + 2)); $this->http_header[$key] = $value; } return strlen($header); } } ####################################################### # TwitterOauth End ######################################################### ############################################ # Oauth Start ################################################## /* Generic exception class */ class OAuthException extends Exception { // pass } class OAuthConsumer { public $key; public $secret; function __construct($key, $secret, $callback_url=NULL) { $this->key = $key; $this->secret = $secret; $this->callback_url = $callback_url; } function __toString() { return "OAuthConsumer[key=$this->key,secret=$this->secret]"; } } class OAuthToken { // access tokens and request tokens public $key; public $secret; /** * key = the token * secret = the token secret */ function __construct($key, $secret) { $this->key = $key; $this->secret = $secret; } /** * generates the basic string serialization of a token that a server * would respond to request_token and access_token calls with */ function to_string() { return "oauth_token=" . OAuthUtil::urlencode_rfc3986($this->key) . "&oauth_token_secret=" . OAuthUtil::urlencode_rfc3986($this->secret); } function __toString() { return $this->to_string(); } } /** * A class for implementing a Signature Method * See section 9 ("Signing Requests") in the spec */ abstract class OAuthSignatureMethod { /** * Needs to return the name of the Signature Method (ie HMAC-SHA1) * @return string */ abstract public function get_name(); /** * Build up the signature * NOTE: The output of this function MUST NOT be urlencoded. * the encoding is handled in OAuthRequest when the final * request is serialized * @param OAuthRequest $request * @param OAuthConsumer $consumer * @param OAuthToken $token * @return string */ abstract public function build_signature($request, $consumer, $token); /** * Verifies that a given signature is correct * @param OAuthRequest $request * @param OAuthConsumer $consumer * @param OAuthToken $token * @param string $signature * @return bool */ public function check_signature($request, $consumer, $token, $signature) { $built = $this->build_signature($request, $consumer, $token); return $built == $signature; } } /** * The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104] * where the Signature Base String is the text and the key is the concatenated values (each first * encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&' * character (ASCII code 38) even if empty. * - Chapter 9.2 ("HMAC-SHA1") */ class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod { function get_name() { return "HMAC-SHA1"; } public function build_signature($request, $consumer, $token) { $base_string = $request->get_signature_base_string(); $request->base_string = $base_string; $key_parts = array( $consumer->secret, ($token) ? $token->secret : "" ); $key_parts = OAuthUtil::urlencode_rfc3986($key_parts); $key = implode('&', $key_parts); return base64_encode(hash_hmac('sha1', $base_string, $key, true)); } } /** * The PLAINTEXT method does not provide any security protection and SHOULD only be used * over a secure channel such as HTTPS. It does not use the Signature Base String. * - Chapter 9.4 ("PLAINTEXT") */ class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod { public function get_name() { return "PLAINTEXT"; } /** * oauth_signature is set to the concatenated encoded values of the Consumer Secret and * Token Secret, separated by a '&' character (ASCII code 38), even if either secret is * empty. The result MUST be encoded again. * - Chapter 9.4.1 ("Generating Signatures") * * Please note that the second encoding MUST NOT happen in the SignatureMethod, as * OAuthRequest handles this! */ public function build_signature($request, $consumer, $token) { $key_parts = array( $consumer->secret, ($token) ? $token->secret : "" ); $key_parts = OAuthUtil::urlencode_rfc3986($key_parts); $key = implode('&', $key_parts); $request->base_string = $key; return $key; } } /** * The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in * [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for * EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a * verified way to the Service Provider, in a manner which is beyond the scope of this * specification. * - Chapter 9.3 ("RSA-SHA1") */ abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod { public function get_name() { return "RSA-SHA1"; } // Up to the SP to implement this lookup of keys. Possible ideas are: // (1) do a lookup in a table of trusted certs keyed off of consumer // (2) fetch via http using a url provided by the requester // (3) some sort of specific discovery code based on request // // Either way should return a string representation of the certificate protected abstract function fetch_public_cert(&$request); // Up to the SP to implement this lookup of keys. Possible ideas are: // (1) do a lookup in a table of trusted certs keyed off of consumer // // Either way should return a string representation of the certificate protected abstract function fetch_private_cert(&$request); public function build_signature($request, $consumer, $token) { $base_string = $request->get_signature_base_string(); $request->base_string = $base_string; // Fetch the private key cert based on the request $cert = $this->fetch_private_cert($request); // Pull the private key ID from the certificate $privatekeyid = openssl_get_privatekey($cert); // Sign using the key $ok = openssl_sign($base_string, $signature, $privatekeyid); // Release the key resource openssl_free_key($privatekeyid); return base64_encode($signature); } public function check_signature($request, $consumer, $token, $signature) { $decoded_sig = base64_decode($signature); $base_string = $request->get_signature_base_string(); // Fetch the public key cert based on the request $cert = $this->fetch_public_cert($request); // Pull the public key ID from the certificate $publickeyid = openssl_get_publickey($cert); // Check the computed signature against the one passed in the query $ok = openssl_verify($base_string, $decoded_sig, $publickeyid); // Release the key resource openssl_free_key($publickeyid); return $ok == 1; } } class OAuthRequest { private $parameters; private $http_method; private $http_url; // for debug purposes public $base_string; public static $version = '1.0'; public static $POST_INPUT = 'php://input'; function __construct($http_method, $http_url, $parameters=NULL) { @$parameters or $parameters = array(); $parameters = array_merge( OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters); $this->parameters = $parameters; $this->http_method = $http_method; $this->http_url = $http_url; } /** * attempt to build up a request from what was passed to the server */ public static function from_request($http_method=NULL, $http_url=NULL, $parameters=NULL) { $scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on") ? 'http' : 'https'; @$http_url or $http_url = $scheme . '://' . $_SERVER['HTTP_HOST'] . ':' . $_SERVER['SERVER_PORT'] . $_SERVER['REQUEST_URI']; @$http_method or $http_method = $_SERVER['REQUEST_METHOD']; // We weren't handed any parameters, so let's find the ones relevant to // this request. // If you run XML-RPC or similar you should use this to provide your own // parsed parameter-list if (!$parameters) { // Find request headers $request_headers = OAuthUtil::get_headers(); // Parse the query-string to find GET parameters $parameters = OAuthUtil::parse_parameters($_SERVER['QUERY_STRING']); // It's a POST request of the proper content-type, so parse POST // parameters and add those overriding any duplicates from GET if ($http_method == "POST" && @strstr($request_headers["Content-Type"], "application/x-www-form-urlencoded") ) { $post_data = OAuthUtil::parse_parameters( file_get_contents(self::$POST_INPUT) ); $parameters = array_merge($parameters, $post_data); } // We have a Authorization-header with OAuth data. Parse the header // and add those overriding any duplicates from GET or POST if (@substr($request_headers['Authorization'], 0, 6) == "OAuth ") { $header_parameters = OAuthUtil::split_header( $request_headers['Authorization'] ); $parameters = array_merge($parameters, $header_parameters); } } return new OAuthRequest($http_method, $http_url, $parameters); } /** * pretty much a helper function to set up the request */ public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) { @$parameters or $parameters = array(); $defaults = array("oauth_version" => OAuthRequest::$version, "oauth_nonce" => OAuthRequest::generate_nonce(), "oauth_timestamp" => OAuthRequest::generate_timestamp(), "oauth_consumer_key" => $consumer->key); if ($token) $defaults['oauth_token'] = $token->key; $parameters = array_merge($defaults, $parameters); return new OAuthRequest($http_method, $http_url, $parameters); } public function set_parameter($name, $value, $allow_duplicates = true) { if ($allow_duplicates && isset($this->parameters[$name])) { // We have already added parameter(s) with this name, so add to the list if (is_scalar($this->parameters[$name])) { // This is the first duplicate, so transform scalar (string) // into an array so we can add the duplicates $this->parameters[$name] = array($this->parameters[$name]); } $this->parameters[$name][] = $value; } else { $this->parameters[$name] = $value; } } public function get_parameter($name) { return isset($this->parameters[$name]) ? $this->parameters[$name] : null; } public function get_parameters() { return $this->parameters; } public function unset_parameter($name) { unset($this->parameters[$name]); } /** * The request parameters, sorted and concatenated into a normalized string. * @return string */ public function get_signable_parameters() { // Grab all parameters $params = $this->parameters; // Remove oauth_signature if present // Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.") if (isset($params['oauth_signature'])) { unset($params['oauth_signature']); } return OAuthUtil::build_http_query($params); } /** * Returns the base string of this request * * The base string defined as the method, the url * and the parameters (normalized), each urlencoded * and the concated with &. */ public function get_signature_base_string() { $parts = array( $this->get_normalized_http_method(), $this->get_normalized_http_url(), $this->get_signable_parameters() ); $parts = OAuthUtil::urlencode_rfc3986($parts); return implode('&', $parts); } /** * just uppercases the http method */ public function get_normalized_http_method() { return strtoupper($this->http_method); } /** * parses the url and rebuilds it to be * scheme://host/path */ public function get_normalized_http_url() { $parts = parse_url($this->http_url); $port = @$parts['port']; $scheme = $parts['scheme']; $host = $parts['host']; $path = @$parts['path']; $port or $port = ($scheme == 'https') ? '443' : '80'; if (($scheme == 'https' && $port != '443') || ($scheme == 'http' && $port != '80')) { $host = "$host:$port"; } return "$scheme://$host$path"; } /** * builds a url usable for a GET request */ public function to_url() { $post_data = $this->to_postdata(); $out = $this->get_normalized_http_url(); if ($post_data) { $out .= '?'.$post_data; } return $out; } /** * builds the data one would send in a POST request */ public function to_postdata() { return OAuthUtil::build_http_query($this->parameters); } /** * builds the Authorization: header */ public function to_header($realm=null) { $first = true; if($realm) { $out = 'Authorization: OAuth realm="' . OAuthUtil::urlencode_rfc3986($realm) . '"'; $first = false; } else $out = 'Authorization: OAuth'; $total = array(); foreach ($this->parameters as $k => $v) { if (substr($k, 0, 5) != "oauth") continue; if (is_array($v)) { throw new OAuthException('Arrays not supported in headers'); } $out .= ($first) ? ' ' : ','; $out .= OAuthUtil::urlencode_rfc3986($k) . '="' . OAuthUtil::urlencode_rfc3986($v) . '"'; $first = false; } return $out; } public function __toString() { return $this->to_url(); } public function sign_request($signature_method, $consumer, $token) { $this->set_parameter( "oauth_signature_method", $signature_method->get_name(), false ); $signature = $this->build_signature($signature_method, $consumer, $token); $this->set_parameter("oauth_signature", $signature, false); } public function build_signature($signature_method, $consumer, $token) { $signature = $signature_method->build_signature($this, $consumer, $token); return $signature; } /** * util function: current timestamp */ private static function generate_timestamp() { return time(); } /** * util function: current nonce */ private static function generate_nonce() { $mt = microtime(); $rand = mt_rand(); return md5($mt . $rand); // md5s look nicer than numbers } } class OAuthServer { protected $timestamp_threshold = 300; // in seconds, five minutes protected $version = '1.0'; // hi blaine protected $signature_methods = array(); protected $data_store; function __construct($data_store) { $this->data_store = $data_store; } public function add_signature_method($signature_method) { $this->signature_methods[$signature_method->get_name()] = $signature_method; } // high level functions /** * process a request_token request * returns the request token on success */ public function fetch_request_token(&$request) { $this->get_version($request); $consumer = $this->get_consumer($request); // no token required for the initial token request $token = NULL; $this->check_signature($request, $consumer, $token); // Rev A change $callback = $request->get_parameter('oauth_callback'); $new_token = $this->data_store->new_request_token($consumer, $callback); return $new_token; } /** * process an access_token request * returns the access token on success */ public function fetch_access_token(&$request) { $this->get_version($request); $consumer = $this->get_consumer($request); // requires authorized request token $token = $this->get_token($request, $consumer, "request"); $this->check_signature($request, $consumer, $token); // Rev A change $verifier = $request->get_parameter('oauth_verifier'); $new_token = $this->data_store->new_access_token($token, $consumer, $verifier); return $new_token; } /** * verify an api call, checks all the parameters */ public function verify_request(&$request) { $this->get_version($request); $consumer = $this->get_consumer($request); $token = $this->get_token($request, $consumer, "access"); $this->check_signature($request, $consumer, $token); return array($consumer, $token); } // Internals from here /** * version 1 */ private function get_version(&$request) { $version = $request->get_parameter("oauth_version"); if (!$version) { // Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present. // Chapter 7.0 ("Accessing Protected Ressources") $version = '1.0'; } if ($version !== $this->version) { throw new OAuthException("OAuth version '$version' not supported"); } return $version; } /** * figure out the signature with some defaults */ private function get_signature_method(&$request) { $signature_method = @$request->get_parameter("oauth_signature_method"); if (!$signature_method) { // According to chapter 7 ("Accessing Protected Ressources") the signature-method // parameter is required, and we can't just fallback to PLAINTEXT throw new OAuthException('No signature method parameter. This parameter is required'); } if (!in_array($signature_method, array_keys($this->signature_methods))) { throw new OAuthException( "Signature method '$signature_method' not supported " . "try one of the following: " . implode(", ", array_keys($this->signature_methods)) ); } return $this->signature_methods[$signature_method]; } /** * try to find the consumer for the provided request's consumer key */ private function get_consumer(&$request) { $consumer_key = @$request->get_parameter("oauth_consumer_key"); if (!$consumer_key) { throw new OAuthException("Invalid consumer key"); } $consumer = $this->data_store->lookup_consumer($consumer_key); if (!$consumer) { throw new OAuthException("Invalid consumer"); } return $consumer; } /** * try to find the token for the provided request's token key */ private function get_token(&$request, $consumer, $token_type="access") { $token_field = @$request->get_parameter('oauth_token'); $token = $this->data_store->lookup_token( $consumer, $token_type, $token_field ); if (!$token) { throw new OAuthException("Invalid $token_type token: $token_field"); } return $token; } /** * all-in-one function to check the signature on a request * should guess the signature method appropriately */ private function check_signature(&$request, $consumer, $token) { // this should probably be in a different method $timestamp = @$request->get_parameter('oauth_timestamp'); $nonce = @$request->get_parameter('oauth_nonce'); $this->check_timestamp($timestamp); $this->check_nonce($consumer, $token, $nonce, $timestamp); $signature_method = $this->get_signature_method($request); $signature = $request->get_parameter('oauth_signature'); $valid_sig = $signature_method->check_signature( $request, $consumer, $token, $signature ); if (!$valid_sig) { throw new OAuthException("Invalid signature"); } } /** * check that the timestamp is new enough */ private function check_timestamp($timestamp) { if( ! $timestamp ) throw new OAuthException( 'Missing timestamp parameter. The parameter is required' ); // verify that timestamp is recentish $now = time(); if (abs($now - $timestamp) > $this->timestamp_threshold) { throw new OAuthException( "Expired timestamp, yours $timestamp, ours $now" ); } } /** * check that the nonce is not repeated */ private function check_nonce($consumer, $token, $nonce, $timestamp) { if( ! $nonce ) throw new OAuthException( 'Missing nonce parameter. The parameter is required' ); // verify that the nonce is uniqueish $found = $this->data_store->lookup_nonce( $consumer, $token, $nonce, $timestamp ); if ($found) { throw new OAuthException("Nonce already used: $nonce"); } } } class OAuthDataStore { function lookup_consumer($consumer_key) { // implement me } function lookup_token($consumer, $token_type, $token) { // implement me } function lookup_nonce($consumer, $token, $nonce, $timestamp) { // implement me } function new_request_token($consumer, $callback = null) { // return a new token attached to this consumer } function new_access_token($token, $consumer, $verifier = null) { // return a new access token attached to this consumer // for the user associated with this token if the request token // is authorized // should also invalidate the request token } } class OAuthUtil { public static function urlencode_rfc3986($input) { if (is_array($input)) { return array_map(array('OAuthUtil', 'urlencode_rfc3986'), $input); } else if (is_scalar($input)) { return str_replace( '+', ' ', str_replace('%7E', '~', rawurlencode($input)) ); } else { return ''; } } // This decode function isn't taking into consideration the above // modifications to the encoding process. However, this method doesn't // seem to be used anywhere so leaving it as is. public static function urldecode_rfc3986($string) { return urldecode($string); } // Utility function for turning the Authorization: header into // parameters, has to do some unescaping // Can filter out any non-oauth parameters if needed (default behaviour) public static function split_header($header, $only_allow_oauth_parameters = true) { $pattern = '/(([-_a-z]*)=("([^"]*)"|([^,]*)),?)/'; $offset = 0; $params = array(); while (preg_match($pattern, $header, $matches, PREG_OFFSET_CAPTURE, $offset) > 0) { $match = $matches[0]; $header_name = $matches[2][0]; $header_content = (isset($matches[5])) ? $matches[5][0] : $matches[4][0]; if (preg_match('/^oauth_/', $header_name) || !$only_allow_oauth_parameters) { $params[$header_name] = OAuthUtil::urldecode_rfc3986($header_content); } $offset = $match[1] + strlen($match[0]); } if (isset($params['realm'])) { unset($params['realm']); } return $params; } // helper to try to sort out headers for people who aren't running apache public static function get_headers() { if (function_exists('apache_request_headers')) { // we need this to get the actual Authorization: header // because apache tends to tell us it doesn't exist $headers = apache_request_headers(); // sanitize the output of apache_request_headers because // we always want the keys to be Cased-Like-This and arh() // returns the headers in the same case as they are in the // request $out = array(); foreach( $headers AS $key => $value ) { $key = str_replace( " ", "-", ucwords(strtolower(str_replace("-", " ", $key))) ); $out[$key] = $value; } } else { // otherwise we don't have apache and are just going to have to hope // that $_SERVER actually contains what we need $out = array(); if( isset($_SERVER['CONTENT_TYPE']) ) $out['Content-Type'] = $_SERVER['CONTENT_TYPE']; if( isset($_ENV['CONTENT_TYPE']) ) $out['Content-Type'] = $_ENV['CONTENT_TYPE']; foreach ($_SERVER as $key => $value) { if (substr($key, 0, 5) == "HTTP_") { // this is chaos, basically it is just there to capitalize the first // letter of every word that is not an initial HTTP and strip HTTP // code from przemek $key = str_replace( " ", "-", ucwords(strtolower(str_replace("_", " ", substr($key, 5)))) ); $out[$key] = $value; } } } return $out; } // This function takes a input like a=b&a=c&d=e and returns the parsed // parameters like this // array('a' => array('b','c'), 'd' => 'e') public static function parse_parameters( $input ) { if (!isset($input) || !$input) return array(); $pairs = explode('&', $input); $parsed_parameters = array(); foreach ($pairs as $pair) { $split = explode('=', $pair, 2); $parameter = OAuthUtil::urldecode_rfc3986($split[0]); $value = isset($split[1]) ? OAuthUtil::urldecode_rfc3986($split[1]) : ''; if (isset($parsed_parameters[$parameter])) { // We have already recieved parameter(s) with this name, so add to the list // of parameters with this name if (is_scalar($parsed_parameters[$parameter])) { // This is the first duplicate, so transform scalar (string) into an array // so we can add the duplicates $parsed_parameters[$parameter] = array($parsed_parameters[$parameter]); } $parsed_parameters[$parameter][] = $value; } else { $parsed_parameters[$parameter] = $value; } } return $parsed_parameters; } public static function build_http_query($params) { if (!$params) return ''; // Urlencode both keys and values $keys = OAuthUtil::urlencode_rfc3986(array_keys($params)); $values = OAuthUtil::urlencode_rfc3986(array_values($params)); $params = array_combine($keys, $values); // Parameters are sorted by name, using lexicographical byte value ordering. // Ref: Spec: 9.1.1 (1) uksort($params, 'strcmp'); $pairs = array(); foreach ($params as $parameter => $value) { if (is_array($value)) { // If two or more parameters share the same name, they are sorted by their value // Ref: Spec: 9.1.1 (1) natsort($value); foreach ($value as $duplicate_value) { $pairs[] = $parameter . '=' . $duplicate_value; } } else { $pairs[] = $parameter . '=' . $value; } } // For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61) // Each name-value pair is separated by an '&' character (ASCII code 38) return implode('&', $pairs); } } ########### # Oauth End ########## ####################################################### # FACEBOOKOAUTH START ############################################### /** * Extends the BaseFacebook class with the intent of using * PHP sessions to store user ids and access tokens. */ class Facebook extends BaseFacebook { /** * Identical to the parent constructor, except that * we start a PHP session to store the user ID and * access token if during the course of execution * we discover them. * * @param Array $config the application configuration. * @see BaseFacebook::__construct in facebook.php */ public function __construct($config) { if (!session_id()) { session_start(); } parent::__construct($config); } protected static $kSupportedKeys = array('state', 'code', 'access_token', 'user_id'); /** * Provides the implementations of the inherited abstract * methods. The implementation uses PHP sessions to maintain * a store for authorization codes, user ids, CSRF states, and * access tokens. */ protected function setPersistentData($key, $value) { if (!in_array($key, self::$kSupportedKeys)) { self::errorLog('Unsupported key passed to setPersistentData.'); return; } $session_var_name = $this->constructSessionVariableName($key); $_SESSION[$session_var_name] = $value; } protected function getPersistentData($key, $default = false) { if (!in_array($key, self::$kSupportedKeys)) { self::errorLog('Unsupported key passed to getPersistentData.'); return $default; } $session_var_name = $this->constructSessionVariableName($key); return isset($_SESSION[$session_var_name]) ? $_SESSION[$session_var_name] : $default; } protected function clearPersistentData($key) { if (!in_array($key, self::$kSupportedKeys)) { self::errorLog('Unsupported key passed to clearPersistentData.'); return; } $session_var_name = $this->constructSessionVariableName($key); unset($_SESSION[$session_var_name]); } protected function clearAllPersistentData() { foreach (self::$kSupportedKeys as $key) { $this->clearPersistentData($key); } } protected function constructSessionVariableName($key) { return implode('_', array('fb', $this->getAppId(), $key)); } } /** * Copyright 2011 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may obtain * a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ if (!function_exists('curl_init')) { throw new Exception('Facebook needs the CURL PHP extension.'); } if (!function_exists('json_decode')) { throw new Exception('Facebook needs the JSON PHP extension.'); } /** * Thrown when an API call returns an exception. * * @author Naitik Shah */ class FacebookApiException extends Exception { /** * The result from the API server that represents the exception information. */ protected $result; /** * Make a new API Exception with the given result. * * @param array $result The result from the API server */ public function __construct($result) { $this->result = $result; $code = isset($result['error_code']) ? $result['error_code'] : 0; if (isset($result['error_description'])) { // OAuth 2.0 Draft 10 style $msg = $result['error_description']; } else if (isset($result['error']) && is_array($result['error'])) { // OAuth 2.0 Draft 00 style $msg = $result['error']['message']; } else if (isset($result['error_msg'])) { // Rest server style $msg = $result['error_msg']; } else { $msg = 'Unknown Error. Check getResult()'; } parent::__construct($msg, $code); } /** * Return the associated result object returned by the API server. * * @return array The result from the API server */ public function getResult() { return $this->result; } /** * Returns the associated type for the error. This will default to * 'Exception' when a type is not available. * * @return string */ public function getType() { if (isset($this->result['error'])) { $error = $this->result['error']; if (is_string($error)) { // OAuth 2.0 Draft 10 style return $error; } else if (is_array($error)) { // OAuth 2.0 Draft 00 style if (isset($error['type'])) { return $error['type']; } } } return 'Exception'; } /** * To make debugging easier. * * @return string The string representation of the error */ public function __toString() { $str = $this->getType() . ': '; if ($this->code != 0) { $str .= $this->code . ': '; } return $str . $this->message; } } /** * Provides access to the Facebook Platform. This class provides * a majority of the functionality needed, but the class is abstract * because it is designed to be sub-classed. The subclass must * implement the four abstract methods listed at the bottom of * the file. * * @author Naitik Shah */ abstract class BaseFacebook { /** * Version. */ const VERSION = '3.1.1'; /** * Default options for curl. */ public static $CURL_OPTS = array( CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 60, CURLOPT_USERAGENT => 'facebook-php-3.1', ); /** * List of query parameters that get automatically dropped when rebuilding * the current URL. */ protected static $DROP_QUERY_PARAMS = array( 'code', 'state', 'signed_request', ); /** * Maps aliases to Facebook domains. */ public static $DOMAIN_MAP = array( 'api' => 'https://api.facebook.com/', 'api_video' => 'https://api-video.facebook.com/', 'api_read' => 'https://api-read.facebook.com/', 'graph' => 'https://graph.facebook.com/', 'www' => 'https://www.facebook.com/', ); /** * The Application ID. * * @var string */ protected $appId; /** * The Application API Secret. * * @var string */ protected $apiSecret; /** * The ID of the Facebook user, or 0 if the user is logged out. * * @var integer */ protected $user; /** * The data from the signed_request token. */ protected $signedRequest; /** * A CSRF state variable to assist in the defense against CSRF attacks. */ protected $state; /** * The OAuth access token received in exchange for a valid authorization * code. null means the access token has yet to be determined. * * @var string */ protected $accessToken = null; /** * Indicates if the CURL based @ syntax for file uploads is enabled. * * @var boolean */ protected $fileUploadSupport = false; /** * Initialize a Facebook Application. * * The configuration: * - appId: the application ID * - secret: the application secret * - fileUpload: (optional) boolean indicating if file uploads are enabled * * @param array $config The application configuration */ public function __construct($config) { $this->setAppId($config['appId']); $this->setApiSecret($config['secret']); if (isset($config['fileUpload'])) { $this->setFileUploadSupport($config['fileUpload']); } $state = $this->getPersistentData('state'); if (!empty($state)) { $this->state = $this->getPersistentData('state'); } } /** * Set the Application ID. * * @param string $appId The Application ID * @return BaseFacebook */ public function setAppId($appId) { $this->appId = $appId; return $this; } /** * Get the Application ID. * * @return string the Application ID */ public function getAppId() { return $this->appId; } /** * Set the API Secret. * * @param string $apiSecret The API Secret * @return BaseFacebook */ public function setApiSecret($apiSecret) { $this->apiSecret = $apiSecret; return $this; } /** * Get the API Secret. * * @return string the API Secret */ public function getApiSecret() { return $this->apiSecret; } /** * Set the file upload support status. * * @param boolean $fileUploadSupport The file upload support status. * @return BaseFacebook */ public function setFileUploadSupport($fileUploadSupport) { $this->fileUploadSupport = $fileUploadSupport; return $this; } /** * Get the file upload support status. * * @return boolean true if and only if the server supports file upload. */ public function useFileUploadSupport() { return $this->fileUploadSupport; } /** * Sets the access token for api calls. Use this if you get * your access token by other means and just want the SDK * to use it. * * @param string $access_token an access token. * @return BaseFacebook */ public function setAccessToken($access_token) { $this->accessToken = $access_token; return $this; } /** * Determines the access token that should be used for API calls. * The first time this is called, $this->accessToken is set equal * to either a valid user access token, or it's set to the application * access token if a valid user access token wasn't available. Subsequent * calls return whatever the first call returned. * * @return string The access token */ public function getAccessToken() { if ($this->accessToken !== null) { // we've done this already and cached it. Just return. return $this->accessToken; } // first establish access token to be the application // access token, in case we navigate to the /oauth/access_token // endpoint, where SOME access token is required. $this->setAccessToken($this->getApplicationAccessToken()); $user_access_token = $this->getUserAccessToken(); if ($user_access_token) { $this->setAccessToken($user_access_token); } return $this->accessToken; } /** * Determines and returns the user access token, first using * the signed request if present, and then falling back on * the authorization code if present. The intent is to * return a valid user access token, or false if one is determined * to not be available. * * @return string A valid user access token, or false if one * could not be determined. */ protected function getUserAccessToken() { // first, consider a signed request if it's supplied. // if there is a signed request, then it alone determines // the access token. $signed_request = $this->getSignedRequest(); if ($signed_request) { // apps.facebook.com hands the access_token in the signed_request if (array_key_exists('oauth_token', $signed_request)) { $access_token = $signed_request['oauth_token']; $this->setPersistentData('access_token', $access_token); return $access_token; } // the JS SDK puts a code in with the redirect_uri of '' if (array_key_exists('code', $signed_request)) { $code = $signed_request['code']; $access_token = $this->getAccessTokenFromCode($code, ''); if ($access_token) { $this->setPersistentData('code', $code); $this->setPersistentData('access_token', $access_token); return $access_token; } } // signed request states there's no access token, so anything // stored should be cleared. $this->clearAllPersistentData(); return false; // respect the signed request's data, even // if there's an authorization code or something else } $code = $this->getCode(); if ($code && $code != $this->getPersistentData('code')) { $access_token = $this->getAccessTokenFromCode($code); if ($access_token) { $this->setPersistentData('code', $code); $this->setPersistentData('access_token', $access_token); return $access_token; } // code was bogus, so everything based on it should be invalidated. $this->clearAllPersistentData(); return false; } // as a fallback, just return whatever is in the persistent // store, knowing nothing explicit (signed request, authorization // code, etc.) was present to shadow it (or we saw a code in $_REQUEST, // but it's the same as what's in the persistent store) return $this->getPersistentData('access_token'); } /** * Retrieve the signed request, either from a request parameter or, * if not present, from a cookie. * * @return string the signed request, if available, or null otherwise. */ public function getSignedRequest() { if (!$this->signedRequest) { if (isset($_REQUEST['signed_request'])) { $this->signedRequest = $this->parseSignedRequest( $_REQUEST['signed_request']); } else if (isset($_COOKIE[$this->getSignedRequestCookieName()])) { $this->signedRequest = $this->parseSignedRequest( $_COOKIE[$this->getSignedRequestCookieName()]); } } return $this->signedRequest; } /** * Get the UID of the connected user, or 0 * if the Facebook user is not connected. * * @return string the UID if available. */ public function getUser() { if ($this->user !== null) { // we've already determined this and cached the value. return $this->user; } return $this->user = $this->getUserFromAvailableData(); } /** * Determines the connected user by first examining any signed * requests, then considering an authorization code, and then * falling back to any persistent store storing the user. * * @return integer The id of the connected Facebook user, * or 0 if no such user exists. */ protected function getUserFromAvailableData() { // if a signed request is supplied, then it solely determines // who the user is. $signed_request = $this->getSignedRequest(); if ($signed_request) { if (array_key_exists('user_id', $signed_request)) { $user = $signed_request['user_id']; $this->setPersistentData('user_id', $signed_request['user_id']); return $user; } // if the signed request didn't present a user id, then invalidate // all entries in any persistent store. $this->clearAllPersistentData(); return 0; } $user = $this->getPersistentData('user_id', $default = 0); $persisted_access_token = $this->getPersistentData('access_token'); // use access_token to fetch user id if we have a user access_token, or if // the cached access token has changed. $access_token = $this->getAccessToken(); if ($access_token && $access_token != $this->getApplicationAccessToken() && !($user && $persisted_access_token == $access_token)) { $user = $this->getUserFromAccessToken(); if ($user) { $this->setPersistentData('user_id', $user); } else { $this->clearAllPersistentData(); } } return $user; } /** * Get a Login URL for use with redirects. By default, full page redirect is * assumed. If you are using the generated URL with a window.open() call in * JavaScript, you can pass in display=popup as part of the $params. * * The parameters: * - redirect_uri: the url to go to after a successful login * - scope: comma separated list of requested extended perms * * @param array $params Provide custom parameters * @return string The URL for the login flow */ public function getLoginUrl($params=array()) { $this->establishCSRFTokenState(); $currentUrl = $this->getCurrentUrl(); $currentUrl = ($_SERVER[SERVER_PORT]==80 ? "http://".$_SERVER[SERVER_NAME] : "https://".$_SERVER[SERVER_NAME])."/accountsettings.php?tab=socialsetup&setupoauth_facebook=2"; // if 'scope' is passed as an array, convert to comma separated list $scopeParams = isset($params['scope']) ? $params['scope'] : null; if ($scopeParams && is_array($scopeParams)) { $params['scope'] = implode(',', $scopeParams); } return $this->getUrl( 'www', 'dialog/oauth', array_merge(array( 'client_id' => $this->getAppId(), 'redirect_uri' => $currentUrl, // possibly overwritten 'state' => $this->state), $params)); } /** * Get a Logout URL suitable for use with redirects. * * The parameters: * - next: the url to go to after a successful logout * * @param array $params Provide custom parameters * @return string The URL for the logout flow */ public function getLogoutUrl($params=array()) { return $this->getUrl( 'www', 'logout.php', array_merge(array( 'next' => $this->getCurrentUrl(), 'access_token' => $this->getAccessToken(), ), $params) ); } /** * Get a login status URL to fetch the status from Facebook. * * The parameters: * - ok_session: the URL to go to if a session is found * - no_session: the URL to go to if the user is not connected * - no_user: the URL to go to if the user is not signed into facebook * * @param array $params Provide custom parameters * @return string The URL for the logout flow */ public function getLoginStatusUrl($params=array()) { return $this->getUrl( 'www', 'extern/login_status.php', array_merge(array( 'api_key' => $this->getAppId(), 'no_session' => $this->getCurrentUrl(), 'no_user' => $this->getCurrentUrl(), 'ok_session' => $this->getCurrentUrl(), 'session_version' => 3, ), $params) ); } /** * Make an API call. * * @return mixed The decoded response */ public function api(/* polymorphic */) { $args = func_get_args(); if (is_array($args[0])) { return $this->_restserver($args[0]); } else { return call_user_func_array(array($this, '_graph'), $args); } } /** * Constructs and returns the name of the cookie that * potentially houses the signed request for the app user. * The cookie is not set by the BaseFacebook class, but * it may be set by the JavaScript SDK. * * @return string the name of the cookie that would house * the signed request value. */ protected function getSignedRequestCookieName() { return 'fbsr_'.$this->getAppId(); } /** * Get the authorization code from the query parameters, if it exists, * and otherwise return false to signal no authorization code was * discoverable. * * @return mixed The authorization code, or false if the authorization * code could not be determined. */ protected function getCode() { if (isset($_REQUEST['code'])) { if ($this->state !== null && isset($_REQUEST['state']) && $this->state === $_REQUEST['state']) { // CSRF state has done its job, so clear it $this->state = null; $this->clearPersistentData('state'); return $_REQUEST['code']; } else { self::errorLog('CSRF state token does not match one provided.'); return false; } } return false; } /** * Retrieves the UID with the understanding that * $this->accessToken has already been set and is * seemingly legitimate. It relies on Facebook's Graph API * to retrieve user information and then extract * the user ID. * * @return integer Returns the UID of the Facebook user, or 0 * if the Facebook user could not be determined. */ protected function getUserFromAccessToken() { try { $user_info = $this->api('/me'); return $user_info['id']; } catch (FacebookApiException $e) { return 0; } } /** * Returns the access token that should be used for logged out * users when no authorization code is available. * * @return string The application access token, useful for gathering * public information about users and applications. */ protected function getApplicationAccessToken() { return $this->appId.'|'.$this->apiSecret; } /** * Lays down a CSRF state token for this process. * * @return void */ protected function establishCSRFTokenState() { if ($this->state === null) { $this->state = md5(uniqid(mt_rand(), true)); $this->setPersistentData('state', $this->state); } } /** * Retrieves an access token for the given authorization code * (previously generated from www.facebook.com on behalf of * a specific user). The authorization code is sent to graph.facebook.com * and a legitimate access token is generated provided the access token * and the user for which it was generated all match, and the user is * either logged in to Facebook or has granted an offline access permission. * * @param string $code An authorization code. * @return mixed An access token exchanged for the authorization code, or * false if an access token could not be generated. */ protected function getAccessTokenFromCode($code, $redirect_uri = null) { if (empty($code)) { return false; } if ($redirect_uri === null) { $redirect_uri = $this->getCurrentUrl(); } try { // need to circumvent json_decode by calling _oauthRequest // directly, since response isn't JSON format. $access_token_response = $this->_oauthRequest( $this->getUrl('graph', '/oauth/access_token'), $params = array('client_id' => $this->getAppId(), 'client_secret' => $this->getApiSecret(), 'redirect_uri' => $redirect_uri, 'code' => $code)); } catch (FacebookApiException $e) { // most likely that user very recently revoked authorization. // In any event, we don't have an access token, so say so. return false; } if (empty($access_token_response)) { return false; } $response_params = array(); parse_str($access_token_response, $response_params); if (!isset($response_params['access_token'])) { return false; } return $response_params['access_token']; } /** * Invoke the old restserver.php endpoint. * * @param array $params Method call object * * @return mixed The decoded response object * @throws FacebookApiException */ protected function _restserver($params) { // generic application level parameters $params['api_key'] = $this->getAppId(); $params['format'] = 'json-strings'; $result = json_decode($this->_oauthRequest( $this->getApiUrl($params['method']), $params ), true); // results are returned, errors are thrown if (is_array($result) && isset($result['error_code'])) { $this->throwAPIException($result); } if ($params['method'] === 'auth.expireSession' || $params['method'] === 'auth.revokeAuthorization') { $this->destroySession(); } return $result; } /** * Invoke the Graph API. * * @param string $path The path (required) * @param string $method The http method (default 'GET') * @param array $params The query/post data * * @return mixed The decoded response object * @throws FacebookApiException */ protected function _graph($path, $method = 'GET', $params = array()) { if (is_array($method) && empty($params)) { $params = $method; $method = 'GET'; } $params['method'] = $method; // method override as we always do a POST $result = json_decode($this->_oauthRequest( $this->getUrl('graph', $path), $params ), true); // results are returned, errors are thrown if (is_array($result) && isset($result['error'])) { $this->throwAPIException($result); } return $result; } /** * Make a OAuth Request. * * @param string $url The path (required) * @param array $params The query/post data * * @return string The decoded response object * @throws FacebookApiException */ protected function _oauthRequest($url, $params) { if (!isset($params['access_token'])) { $params['access_token'] = $this->getAccessToken(); } // json_encode all params values that are not strings foreach ($params as $key => $value) { if (!is_string($value)) { $params[$key] = json_encode($value); } } return $this->makeRequest($url, $params); } /** * Makes an HTTP request. This method can be overridden by subclasses if * developers want to do fancier things or use something other than curl to * make the request. * * @param string $url The URL to make the request to * @param array $params The parameters to use for the POST body * @param CurlHandler $ch Initialized curl handle * * @return string The response text */ protected function makeRequest($url, $params, $ch=null) { if (!$ch) { $ch = curl_init(); } $opts = self::$CURL_OPTS; if ($this->useFileUploadSupport()) { $opts[CURLOPT_POSTFIELDS] = $params; } else { $opts[CURLOPT_POSTFIELDS] = http_build_query($params, null, '&'); } $opts[CURLOPT_URL] = $url; // disable the 'Expect: 100-continue' behaviour. This causes CURL to wait // for 2 seconds if the server does not support this header. if (isset($opts[CURLOPT_HTTPHEADER])) { $existing_headers = $opts[CURLOPT_HTTPHEADER]; $existing_headers[] = 'Expect:'; $opts[CURLOPT_HTTPHEADER] = $existing_headers; } else { $opts[CURLOPT_HTTPHEADER] = array('Expect:'); } curl_setopt_array($ch, $opts); $result = curl_exec($ch); if (curl_errno($ch) == 60) { // CURLE_SSL_CACERT self::errorLog('Invalid or no certificate authority found, '. 'using bundled information'); curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '/fb_ca_chain_bundle.crt'); $result = curl_exec($ch); } if ($result === false) { $e = new FacebookApiException(array( 'error_code' => curl_errno($ch), 'error' => array( 'message' => curl_error($ch), 'type' => 'CurlException', ), )); curl_close($ch); throw $e; } curl_close($ch); return $result; } /** * Parses a signed_request and validates the signature. * * @param string $signed_request A signed token * @return array The payload inside it or null if the sig is wrong */ protected function parseSignedRequest($signed_request) { list($encoded_sig, $payload) = explode('.', $signed_request, 2); // decode the data $sig = self::base64UrlDecode($encoded_sig); $data = json_decode(self::base64UrlDecode($payload), true); if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') { self::errorLog('Unknown algorithm. Expected HMAC-SHA256'); return null; } // check sig $expected_sig = hash_hmac('sha256', $payload, $this->getApiSecret(), $raw = true); if ($sig !== $expected_sig) { self::errorLog('Bad Signed JSON signature!'); return null; } return $data; } /** * Build the URL for api given parameters. * * @param $method String the method name. * @return string The URL for the given parameters */ protected function getApiUrl($method) { static $READ_ONLY_CALLS = array('admin.getallocation' => 1, 'admin.getappproperties' => 1, 'admin.getbannedusers' => 1, 'admin.getlivestreamvialink' => 1, 'admin.getmetrics' => 1, 'admin.getrestrictioninfo' => 1, 'application.getpublicinfo' => 1, 'auth.getapppublickey' => 1, 'auth.getsession' => 1, 'auth.getsignedpublicsessiondata' => 1, 'comments.get' => 1, 'connect.getunconnectedfriendscount' => 1, 'dashboard.getactivity' => 1, 'dashboard.getcount' => 1, 'dashboard.getglobalnews' => 1, 'dashboard.getnews' => 1, 'dashboard.multigetcount' => 1, 'dashboard.multigetnews' => 1, 'data.getcookies' => 1, 'events.get' => 1, 'events.getmembers' => 1, 'fbml.getcustomtags' => 1, 'feed.getappfriendstories' => 1, 'feed.getregisteredtemplatebundlebyid' => 1, 'feed.getregisteredtemplatebundles' => 1, 'fql.multiquery' => 1, 'fql.query' => 1, 'friends.arefriends' => 1, 'friends.get' => 1, 'friends.getappusers' => 1, 'friends.getlists' => 1, 'friends.getmutualfriends' => 1, 'gifts.get' => 1, 'groups.get' => 1, 'groups.getmembers' => 1, 'intl.gettranslations' => 1, 'links.get' => 1, 'notes.get' => 1, 'notifications.get' => 1, 'pages.getinfo' => 1, 'pages.isadmin' => 1, 'pages.isappadded' => 1, 'pages.isfan' => 1, 'permissions.checkavailableapiaccess' => 1, 'permissions.checkgrantedapiaccess' => 1, 'photos.get' => 1, 'photos.getalbums' => 1, 'photos.gettags' => 1, 'profile.getinfo' => 1, 'profile.getinfooptions' => 1, 'stream.get' => 1, 'stream.getcomments' => 1, 'stream.getfilters' => 1, 'users.getinfo' => 1, 'users.getloggedinuser' => 1, 'users.getstandardinfo' => 1, 'users.hasapppermission' => 1, 'users.isappuser' => 1, 'users.isverified' => 1, 'video.getuploadlimits' => 1); $name = 'api'; if (isset($READ_ONLY_CALLS[strtolower($method)])) { $name = 'api_read'; } else if (strtolower($method) == 'video.upload') { $name = 'api_video'; } return self::getUrl($name, 'restserver.php'); } /** * Build the URL for given domain alias, path and parameters. * * @param $name string The name of the domain * @param $path string Optional path (without a leading slash) * @param $params array Optional query parameters * * @return string The URL for the given parameters */ protected function getUrl($name, $path='', $params=array()) { $url = self::$DOMAIN_MAP[$name]; if ($path) { if ($path[0] === '/') { $path = substr($path, 1); } $url .= $path; } if ($params) { $url .= '?' . http_build_query($params, null, '&'); } return $url; } /** * Returns the Current URL, stripping it of known FB parameters that should * not persist. * * @return string The current URL */ protected function getCurrentUrl() { if (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1) || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' ) { $protocol = 'https://'; } else { $protocol = 'http://'; } $currentUrl = $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; $parts = parse_url($currentUrl); $query = ''; if (!empty($parts['query'])) { // drop known fb params $params = explode('&', $parts['query']); $retained_params = array(); foreach ($params as $param) { if ($this->shouldRetainParam($param)) { $retained_params[] = $param; } } if (!empty($retained_params)) { $query = '?'.implode($retained_params, '&'); } } // use port if non default $port = isset($parts['port']) && (($protocol === 'http://' && $parts['port'] !== 80) || ($protocol === 'https://' && $parts['port'] !== 443)) ? ':' . $parts['port'] : ''; // rebuild return $protocol . $parts['host'] . $port . $parts['path'] . $query; } /** * Returns true if and only if the key or key/value pair should * be retained as part of the query string. This amounts to * a brute-force search of the very small list of Facebook-specific * params that should be stripped out. * * @param string $param A key or key/value pair within a URL's query (e.g. * 'foo=a', 'foo=', or 'foo'. * * @return boolean */ protected function shouldRetainParam($param) { foreach (self::$DROP_QUERY_PARAMS as $drop_query_param) { if (strpos($param, $drop_query_param.'=') === 0) { return false; } } return true; } /** * Analyzes the supplied result to see if it was thrown * because the access token is no longer valid. If that is * the case, then the persistent store is cleared. * * @param $result array A record storing the error message returned * by a failed API call. */ protected function throwAPIException($result) { $e = new FacebookApiException($result); switch ($e->getType()) { // OAuth 2.0 Draft 00 style case 'OAuthException': // OAuth 2.0 Draft 10 style case 'invalid_token': // REST server errors are just Exceptions case 'Exception': $message = $e->getMessage(); if ((strpos($message, 'Error validating access token') !== false) || (strpos($message, 'Invalid OAuth access token') !== false)) { $this->setAccessToken(null); $this->user = 0; $this->clearAllPersistentData(); } } throw $e; } /** * Prints to the error log if you aren't in command line mode. * * @param string $msg Log message */ protected static function errorLog($msg) { // disable error log if we are running in a CLI environment // @codeCoverageIgnoreStart if (php_sapi_name() != 'cli') { error_log($msg); } // uncomment this if you want to see the errors on the page // print 'error_log: '.$msg."\n"; // @codeCoverageIgnoreEnd } /** * Base64 encoding that doesn't need to be urlencode()ed. * Exactly the same as base64_encode except it uses * - instead of + * _ instead of / * * @param string $input base64UrlEncoded string * @return string */ protected static function base64UrlDecode($input) { return base64_decode(strtr($input, '-_', '+/')); } /** * Destroy the current session */ public function destroySession() { $this->setAccessToken(null); $this->user = 0; $this->clearAllPersistentData(); } /** * Each of the following four methods should be overridden in * a concrete subclass, as they are in the provided Facebook class. * The Facebook class uses PHP sessions to provide a primitive * persistent store, but another subclass--one that you implement-- * might use a database, memcache, or an in-memory cache. * * @see Facebook */ /** * Stores the given ($key, $value) pair, so that future calls to * getPersistentData($key) return $value. This call may be in another request. * * @param string $key * @param array $value * * @return void */ abstract protected function setPersistentData($key, $value); /** * Get the data for $key, persisted by BaseFacebook::setPersistentData() * * @param string $key The key of the data to retrieve * @param boolean $default The default value to return if $key is not found * * @return mixed */ abstract protected function getPersistentData($key, $default = false); /** * Clear the data with $key from the persistent storage * * @param string $key * @return void */ abstract protected function clearPersistentData($key); /** * Clear all data from the persistent storage * * @return void */ abstract protected function clearAllPersistentData(); } ####################### # Facebookoauth End ################################################ ################################################## # Facebook Start ##################### if($_GET[setupoauth_facebook]=="1") { //this is for RIOGenesis app if (strstr($_SERVER[SERVER_NAME],"matraex")) { //$facebook_appid = "102933686492124"; //$facebook_appsecret = "f418cb9472f1e8c14a17739b0e433b81"; // updated with new app 07302015 JT $facebook_appid = "1506568339635093"; $facebook_appsecret = "eeceb917384971fba3ec131d22e3cbf3"; } else { //$facebook_appid = "490524621009706"; //$facebook_appsecret = " d49b751e9db5fd31a0a7b1c145d35139"; // updated with new app 07302015 JT $facebook_appid = "1506568339635093"; $facebook_appsecret = "eeceb917384971fba3ec131d22e3cbf3"; } $facebook_appaccesstoken = $facebook_appid."|".$facebook_appsecret; $facebook = new Facebook(array( 'appId' => $facebook_appid, 'secret' => $facebook_appsecret, 'cookie' => true )); $current_accesstoken = $facebook->getAccessToken(); if($current_accesstoken==$facebook_appaccesstoken) { $fb_loginUrl = $facebook->getLoginUrl(array( 'canvas' => 1, 'fbconnect' => 0, 'scope' => 'publish_actions' )); } else { $fb_user = $facebook->getUser(); $fb_logoutUrl = $facebook->getLogoutUrl(); } if ($fb_user) { try { // Proceed knowing you have a logged in user who's authenticated. $facebook_user_data = $facebook->api('/me'); $facebook_user_accesstoken = $facebook->getAccessToken(); print_r($facebook_user_data); } catch (FacebookApiException $e) { error_log($e); $user = null; } } else { if($fb_loginUrl) { header('Location: '.$fb_loginUrl); exit_wrapper (); } } } // $attachment has the following options: // $attachment[name] - this is the title or the post, such as story title when posting a story link // $attachment[caption] - Caption of the Post // $attachment[link] - URL or where the name/title links to // $attachment[description] - description/text of the post // $attachment[picture] - description/text of the post function facebook_post($oauthuserid='',$messagetopost='',$attachment=0){ $oauth_accounts = getoauthuserinfo(0,0,0,$oauthuserid); if($oauth_accounts[0][oauthuserkey]){ //this is token and token secret for the USERS oauth authentication $facebook_access_token = trim($oauth_accounts[0][oauthuserkey]); $facebook_userid = trim($oauth_accounts[0][oauthuserproviderref]); $params[access_token] = $facebook_access_token; $params[message] = $messagetopost; if(count($attachment)>0){ $params[name] = $attachment[name]; $params[caption] = $attachment[caption]; $params[link] = $attachment[link]; $params[description] = $attachment[description]; $params[picture] = $attachment[picture]; } $url = "https://graph.facebook.com/$facebook_userid/feed"; $ch = curl_init(); curl_setopt_array($ch, array( CURLOPT_URL => $url, CURLOPT_POSTFIELDS => $params, CURLOPT_RETURNTRANSFER => true, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_VERBOSE => true )); $result = curl_exec($ch); $result = json_decode($result); if($result->id){ return $result->id; } else { return false; } }else{ return false; } } function facebook_verify($oauthuserid=''){ $oauth_accounts = getoauthuserinfo(0,0,0,$oauthuserid); if(trim($oauth_accounts[0][oauthuserprovider])!="facebook"){ return false; } if($oauth_accounts[0][oauthuserkey]){ //this is token and token secret for the USERS oauth authentication $facebook_access_token = trim($oauth_accounts[0][oauthuserkey]); $facebook_userid = trim($oauth_accounts[0][oauthuserproviderref]); //$params[access_token] = $facebook_access_token; $url = "https://graph.facebook.com/me?access_token=".$facebook_access_token; $facebook_returned = @file_get_contents($url); if($facebook_returned === FALSE) { "";//we have an error//echo "Social Sharing Service Unavailable at this time."; } $picture_url = "https://graph.facebook.com/".$facebook_userid."/picture"; social_update_avatar($oauthuserid,$picture_url); $result = json_decode($facebook_returned); //d(facebook_verifyresult,$result); if($result->id){ return true; } else { return false; } }else{ return false; } } ################################################## # Facebook End ##################### ################################################# # Bit.ly Bitly Start ########################### $bitly_riogenesis_username = "riogenesis"; $bitly_riogenesis_apikey = "R_f56673c05f4ec2f37b2cf664b3e82908"; function getBitlyShortUrl($url=''){ global $bitly_riogenesis_username,$bitly_riogenesis_apikey; return get_bitly_short_url($url,$bitly_riogenesis_username,$bitly_riogenesis_apikey,'txt'); } function get_bitly_short_url($url,$login,$appkey,$format='txt') { $connectURL = 'http://api.bit.ly/v3/shorten?login='.$login.'&apiKey='.$appkey.'&uri='.urlencode($url).'&format='.$format; return curl_get_result($connectURL); } /* returns expanded url */ function get_bitly_long_url($url,$login,$appkey,$format='txt') { $connectURL = 'http://api.bit.ly/v3/expand?login='.$login.'&apiKey='.$appkey.'&shortUrl='.urlencode($url).'&format='.$format; return curl_get_result($connectURL); } /* returns a result form url */ function curl_get_result($url) { $ch = curl_init(); $timeout = 5; curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout); $data = curl_exec($ch); curl_close($ch); return $data; } ######################### # Bit.ly Bitly End ################################################### /*** * FB_CURL */ function curl_json ($url="",$post,$params,$json=0){ $host = "dev.rio.matraex.com"; if (!$url) $url=$host; $ch = curl_init(); if ($post){ curl_setopt_array($ch, array( CURLOPT_URL => $url, CURLOPT_POSTFIELDS => $params, CURLOPT_RETURNTRANSFER => true, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_VERBOSE => true )); }else{ // GET if ($json) curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/json')); curl_setopt($ch, CURLOPT_POSTFIELDS, null); curl_setopt($ch, CURLOPT_POST, FALSE); curl_setopt($ch, CURLOPT_HTTPGET, TRUE); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_VERBOSE, true); } $result = curl_exec($ch); if ($json) $r = json_decode($result,true); if (!r && $result){ $str = substr(substr($result,0,-1),1); $r = json_decode($str,true); if ($r) $result = $r; } d(curlresult,$result); return $result; } function freosalesforceapi_error($property, $apn,$error, $data='', $client=false,$additionalmessage="") { global $soapwsdl; $property = trim($property); $apn = trim($apn); $error = trim($error); d(apn,$apn); d(error,$error); d(property,$property); dlog('freosalesforceapi',"freosalesforceapi_error($apn) - $property - $error) ".print_r($data, true)); $to="freoemailaddress"; $to='michael@matraex.com'; $to='no-reply@riogenesis.com'; $to='helpdesk-support@matraex.com,ekim@pretiumpartnersllc.com'; $from=FREODOCUMENTBOXEMAIL_FROM; $subject ="RIO -> FREOSALESFORCE API Error"; $dataout = $data; if(is_array($data) && $data) { $dataout = "data = "; foreach($data as $k=>$v) $dataout.=" $k=>'$v',"; } $body="An error has been detected in the RIO -> FREOSALESFORCE API
 " . $additionalmessage . " "; if($dataout) $body.=" "; if($client) { $lastrequest = $client->__getLastRequest(); if($lastrequest) { $lastrequest=htmlentities($lastrequest); $body.=""; } } $body.="
Time: ".dttime_format(time())."
Property: $property
RIO User: ".get_login_info(loginid())."
Parameters: $dataout
Last Request: $lastrequest
APN: $apn
APN: $apn
Error: $error
WSDL: $soapwsdl
HTTP_HOST: $_SERVER[HTTP_HOST]
REMOTE_ADDR: $_SERVER[REMOTE_ADDR]
"; html_mail($to,$from,$subject,$body,$attachmentdocumentid=0,$headerarr=""); } function freosalesforceapi_statusupdate($offerid,$statustext,$propertyid=0) { return false; // Temporary disabled per client request MTX 21378 global $soapwsdl; dlog('freosalesforceapi',"$property[propertyid] | $offerID - $propertyid | $apn | SOAPCLIENT ($soapwsdl) Status $statustext"); $soapwsdl = "http://riomsgprocessor.cloudapp.net/riomsgprocessor.svc?wsdl"; if(app_get('setting_freoapi_sandbox')|| developer_variable('SOAP_SandBOX')) $soapwsdl = "http://4e598a44cdd3446288a316353ab9199a.cloudapp.net/riomsgprocessor.svc?wsdl"; // sandbox testing instance - use test apn: 54855 if ($offerid) { $sql = "select * from tbloffer join tblavailablepropertyentry using (offerid) where clientcompanyid = 92 and offerid = ".db_number($offerid); $offer = db_first($sql); if(!$offer) return "Invalid Offer for FREO Update ID: $offerid"; $property = get_property($offer[propertyid]); } if (db_number($propertyid) && !$property) $property = get_property($propertyid); if(!$property) return "Invalid Property: $propertyid"; $propdesc = "$property[propertyaddress] $property[propertycity] $property[propertystate] $property[propertyzip]"; $apn = get_propertyextensionentry($property[propertyid],propertyextensionuniqueid); if(!$apn) $apn = get_propertyextensionentry($property[propertyid],propertyextensionparcelapn); if(!$apn) return "No Unique ID(APN) Set on property for FREO Update: $property[propertyaddress]"; $arr[apn] = $apn; $arr[value] = $statustext; try { dlog('freosalesforceapi',"$property[propertyid] | $offer[offerid] | $apn | SOAPCLIENT ($soapwsdl) Status $statustext"); ini_set("default_socket_timeout", 100); // this will extend SOAP socket to 100 sec $client = new SoapClient($soapwsdl,array("trace"=>1, "connection_timeout"=>100) ); $ret = $client->PropertyUpdate_Stage($arr); //d(ret,$ret,0,0,"", ""); //$response = $client->SomeSoapRequest(); } catch(Exception $ex) { //d(ex,$ex); $error = "RIO -> FREO Connectivity Error - faultcode: ".$ex->faultcode." faultstring: ".$ex->faultstring; $additionalmessage = "
Unexpected response recived from FREO Servers while attempting to connect.
RIO and FREO Tech Support have been notified.
"; freosalesforceapi_error($propdesc, $apn,$error,$arr, $client,$additionalmessage); return "$error" . $additionalmessage . "We applogize for inconviniece. Please try your request latter."; } $outarr = (array)$ret->PropertyUpdate_StageResult; if ($outarr[ErrorMsg]) { dlog('freosalesforceapi',"$property[propertyid] | $offer[offerid] | $apn | Error: $outarr[ErrorMsg] "); return $outarr[ErrorMsg]; } else{ $billingtribecaid = get_propertyextensionentry($property[propertyid],propertyextensionbillingtribecaid); dlog('freosalesforceapi',"$property[propertyid] | $offer[offerid] | $apn | SOAPCLIENT ($soapwsdl) Status :".print_r($outarr,true)); if(!$billingtribecaid && $outarr[TribecaID] ) property_ext_save($property[propertyid],propertyextensionbillingtribecaid, $outarr[TribecaID]); // We dont have an error message time to update db. $sql = "insert into tblofferstage (offerid, offerstagecreatedby, offerstagestatus) VALUES (" . db_number($offerid) . "," . db_number(loginid()) . "," . db_tick($statustext) . ")"; db_exec($sql); } return false; // On Success return false } function freosalesforceapi_property($offerid, $section) { if(!db_number($offerid)) return; return true; // Temporary disabled on CLient request MTX 21378 $clientcompanyid = 92; //freo clientcompanyid $uniquepe = 'propertyextensionuniqueid'; //use this value as the primary uniqueid $uniquepe2 = 'propertyextensionparcelapn'; //if we dont' have a value, use this. $uniquesf = 'apn'; $extens = get_propertyextensions_byconfigtypematch("freosalesforceapifunction",'',$clientcompanyid, false ); $sql = "select * from tbloffer join tblproperty using(propertyid) where offerid = ".db_number($offerid); $offer = db_first($sql); if(!$offer) ddie("Invalid offer"); $propertyid = $offer[propertyid]; d(extens,$extens); $extensmap = array_column($extens, propertyextensionconfigvalue, propertyextensionkey); d(extensmap,$extensmap); $getkeys = $extensmap; $getkeys[$uniquepe] = $uniquepe; $getkeys[$uniquepe2] = $uniquepe2; $sql = "select * from tblpropertyextensionentry where propertyid = ".db_number($propertyid)." and coalesce(propertyextensionentryvalue,'') <> '' "; $values = db_query($sql); $values = array_column($values, propertyextensionentryvalue, propertyextensionkey); d(values, $values); $apn = $values[$uniquepe]; if(!$apn) { $uniquepe=$uniquepe2; $apn = $values[$uniquepe]; } foreach($values as $k=>$v) { unset($values[$k]); $k = str_replace("_offer$offerid","",$k); $values[$k] = $v; } $hoaname = $values[propertyextensionhoaname1]; //keep this set so that as the WSDL changes global $soapwsdl; $soapwsdl = "http://riomsgprocessor.cloudapp.net/riomsgprocessor.svc?wsdl"; //live site testing instance apn: 108xxx? d(sandbox,app_get('setting_freoapi_sandbox')); if(app_get('setting_freoapi_sandbox')) $soapwsdl = "http://4e598a44cdd3446288a316353ab9199a.cloudapp.net/riomsgprocessor.svc?wsdl"; // sandbox testing instance - use test apn: 54855 $property = get_property($propertyid); $propdesc = "$property[propertyaddress] $property[propertycity] $property[propertystate] $property[propertyzip]"; try { dlog('freosalesforceapi',"$offer[propertyid] $offer[offerid] SOAPCLIENT ($soapwsdl)"); ini_set("default_socket_timeout", 100); // this will extend SOAP socket to 100 sec $client = new SoapClient($soapwsdl, array('trace'=>1, "connection_timeout"=>100 ) ); //$response = $client->SomeSoapRequest(); } catch(Exception $ex) { d(ex,$ex); $error = "RIO -> FREO Connectivity Error - faultcode: ".$ex->faultcode." faultstring: ".$ex->faultstring; $additionalmessage = "
Unexpected Network Communication received from FREO Servers while attempting to connect.
RIO and FREO Tech Support have been notified.
"; freosalesforceapi_error($propdesc, $values[$uniquepe],$error, $client, $additionalmessage); return "$error" . $additionalmessage . "We applogize for inconviniece. Please try your request latter."; //freosalesforceapi_error("Connectivity error ) } $fs = $client->__getFunctions(); $types =$client->__getTypes() ; d(freo_functions, $fs); d(freo_types, $types); d(property,$property); d(values,$values); if($hoaname == 'N/A') $skiphoafields = 1; d("extensmap",$extensmap); arsort($extensmap ); //put the property updates before the HOA updates d("extensmap",$extensmap); foreach($extensmap as $fld => $func) { //d($fld,array_keys($exclusionmap)); if(!$func) { d("invalid configuration field $fld is somehow turned on but not with a value"); continue; } $arr = array(); $arr[$uniquesf] = $values[$uniquepe]; $value = $values[$fld]; if(!strlen($value)) continue; // skip any empty columns $cftype = $extens[$fld][customfieldtypename]; if($cftype == 'money') $value = str_replace("$",'',$value) ; if($cftype == 'money') $value = str_replace(",",'',$value) ; if($cftype == 'timedatepicker') { $value = date("c",strtotime($value)) ; // put this in ISO8601 formatted timestamp } $arr[value] = trim($value); // trim extra spaces // if(strstr($func,HoaUpdate ) ) { $foundaddnew = false; d($_POST[addnew],$hoaname); if($_POST[addnew] ) $foundaddnew = array_search($hoaname,$_POST[addnew]); if(strlen($foundaddnew)) // if we have problems with creating HOA please look in MTX 19249 for pseudo code for solution { $createarr=array(); unset($_POST[addnew][$foundaddnew]); $createarr[value] = trim($hoaname); $createarr[apn] = $apn; try { dlog('freosalesforceapi',"Hoa_Create $ofr[propertyid] $ofr[offerid] $createarr[apn] '$createarr[value]'"); $ret = $client->Hoa_Create($createarr); d(createarr,$createarr); d(create_ret,$ret); } catch(SoapFault $ex) { if($ex->faultcode == "HTTP") { $error = "RIO -> FREO API Error $ret = $client->Hoa_Create($arr); operation: $func - faultcode: ".$ex->faultcode." faultstring: ".$ex->faultstring; $additionalmessage = "
Unexpected Network Communication received from FREO Servers while attempting to connect.
RIO and FREO Tech Support have been notified.
"; freosalesforceapi_error($propdesc, $values[$uniquepe],$error,$createarr, $client,$additonalmessage); //if we run into a connectivity issue, lets stop attempting to connect - return return $error; } $error = "RIO -> FREO API Error field:$fld operation: $func - faultcode: ".$ex->faultcode." faultstring: ".$ex->faultstring; $additionalmessage = "
Unexpected Response received from FREO Servers.
RIO and FREO Tech Support have been notified.
"; freosalesforceapi_error($propdesc, $values[$uniquepe],$error,$createarr, $client,$additionalmessage); $skiphoafields =1; // Skip all hoa fields HOA is broken continue; } dlog('freosalesforceapi'," $createarr[apn] '$createarr[value]' HOA Create result :" . print_r($ret->Hoa_CreateResult,true) ); if($ret->Hoa_CreateResult->ErrorMsg) { $skiphoafields =1; // Skip all hoa fields HOA is broken $error = "RIO -> FREO API Error Hoa_Create(".print_r($createarr,true)."); Error: ".$ret->Hoa_CreateResult->ErrorMsg; if (!strstr($error,"Could not find HOAs for") ) // Dont send email if error type contains this string. if (!strstr($error,"already exists")){ // Dont send email if HOA already exists just notify user $additionalmessage = "
Unexpected Response received from FREO Servers.
RIO and FREO Tech Support have been notified.
"; freosalesforceapi_error($propdesc, $values[$uniquepe],$error,$createarr, $client,$additionalmessage); } //if we run into a connectivity issue, lets stop attempting to connect - return return "HOA Did not save -> ".$ret->Hoa_CreateResult->ErrorMsg ; } //ddie("dont continue"); } if($skiphoafields) { d("skipping update of the HOA fields since it is marked as 'N/A'"); continue; } $arr[hoaName] = $hoaname; } d($fld." | ".$func,$arr); if(!$func) { d("invalid configuration field $fld is somehow turned on but not with a value"); continue; } try { $ret = $client->$func($arr); d(ret,$ret); } catch(SoapFault $ex) { if($ex->faultcode == "HTTP") { $error = "RIO -> FREO API Error field:$fld operation: $func - faultcode: ".$ex->faultcode." faultstring: ".$ex->faultstring; $additionalmessage = "
Unexpected Network Communication received from FREO Servers while attempting to connect.
RIO and FREO Tech Support have been notified.
"; freosalesforceapi_error($propdesc, $values[$uniquepe],$error,$arr, $client,$additionalmessage); //if we run into a connectivity issue, lets stop attempting to connect - return return $error; } $error = "RIO -> FREO API Error field:$fld operation: $func - faultcode: ".$ex->faultcode." faultstring: ".$ex->faultstring; $additionalmessage = "
Unexpected Response received from FREO Servers.
RIO and FREO Tech Support have been notified.
"; freosalesforceapi_error($propdesc, $values[$uniquepe],$error,$arr, $client,$additionalmessage); continue; } //$ret has the full response foreach($ret as $response) { $ret = $response; break; } //d(ret,$ret); dlog('freosalesforceapi',"$offer[propertyid] $offer[offerid] SOAPFUNC->$func(apn=>$apn,value=>'$arr[value]',hoaName=>'$arr[hoaName]') == (error=>'$ret->ErrorMsg', Succeeded=>'$ret->Succeeded' $property[propertyaddress])"); //d(ret,$ret); //need to verify whether their is an APN error or not if(strstr($ret->ErrorMsg , 'APNERROR')) return $ret->ErrorMsg; //need to verify whether their is an APN error or not if(strstr($ret->ErrorMsg , 'HOAERROR')) return $ret->ErrorMsg; if($ret->ErrorMsg ) { $error = "RIO -> FREO API Error field:$fld operation:$func - API Returned Error:" .$ret->ErrorMsg; $additionalmessage = "
Unexpected Response received from FREO Servers.
RIO and FREO Tech Support have been notified.
"; freosalesforceapi_error($propdesc, $values[$uniquepe],$error,$arr,$client,$additionalmessage); //this type of message is non fatal //continue; if(strstr($func,HoaUpdate ) ) { $skiphoafields =1; // Hoa Update has failed do not update HOA fields. } } if(!$processed_documents ) { //upload all documents at the bottom of the extension loop if at least one extension was uploaded without a problem $processed_documents++; $docextens = gettab_extensions($section, '','','1',$clientcompanyid); foreach($docextens as $fld =>$docexten) { $ret = ''; if($docexten[customfieldtypename] == 'documentupload' && $values[$docexten[propertyextensionkey]] > 1){ $docid = $values[$docexten[propertyextensionkey]]; if (db_number($docid) && $apn) $ret = freosalesforceapi_sendfile($apn,$docid); if ( strlen($ret)>2 ) set_message($ret,fileerror); } } } continue; } d(offer,$offer); d(section,$section); return true; // this must return true or the Agent gets an error on their page. } /** * @name freosalesforceapi_sendfile * @param string $apn APN * @param integer $documentid tbldocument.documentid. */ function freosalesforceapi_sendfile($apn,$documentid){ return false; // Temporary disabled per Client Request MTX 21378 if (!$apn) return "Error: Missing APN"; if (!db_number($documentid) ) return "Error: Missinf DocumentID"; // init SOAP global $soapwsdl; if(app_get('setting_freoapi_sandbox') || $_SESSION[developer][SOAP_SandBOX]) $soapwsdl = "http://4e598a44cdd3446288a316353ab9199a.cloudapp.net/riomsgprocessor.svc?wsdl"; // sandbox testing instance - use test apn: 54855 else $soapwsdl = "http://riomsgprocessor.cloudapp.net/riomsgprocessor.svc?wsdl"; //live site testing instance apn: 108xxx? // Make Soap call /**** * Soap said: Property_FileUpload { string apn; string fileName; base64Binary buffer; */ try { dlog('freosalesforceapi',"$apn $sendfile SOAPCLIENT ($soapwsdl)"); ini_set("default_socket_timeout", 100); // this will extend SOAP socket to 100 sec $client = new SoapClient($soapwsdl, array('trace'=>1, "connection_timeout"=>100 ) ); } catch(Exception $ex) { d(ex,$ex); $error = "RIO -> FREO Connectivity Error - faultcode: ".$ex->faultcode." faultstring: ".$ex->faultstring; $additionalmessage = "
Unexpected Network Communication received from FREO Servers while attempting to connect.
RIO and FREO Tech Support have been notified.
"; freosalesforceapi_error($apn, $sendfile,$error, $client,$additionalmessage); return "$error"; } if (1==2) { $fs = $client->__getFunctions(); $types =$client->__getTypes() ; d(freo_functions, $fs); d(freo_types, $types); d(property,$property); d(values,$values); } if ($documentid) { $sql = "select documentid, documentname from tbldocument where documentid = " . db_number($documentid) . " Limit 1"; $docarr = array_shift ( db_query ($sql) ); $path = $_SERVER[DOCUMENT_ROOT]."/document/".getrelativedocumentdir($docarr[documentid]).$docarr[documentname]; $sendfile = $docarr[documentid] . "_" .$docarr[documentname]; if (file_exists($path) ) { $fh = fopen($path, "r"); $bytearray = fread($fh, filesize($path)); fclose($fh); } else return "File not found : " . (is_developer() ? $path : str_replace ($_SERVER['DOCUMENT_ROOT'],"",$path)); } try { dlog('freosalesforceapi',"$offer[propertyid] $offer[offerid] SOAPFUNC->Property_FileUpload(apn=>$apn,fileName=>$sendfile)"); $ret = (array) $client ->Property_FileUpload(array('apn'=>$apn,'fileName'=>$sendfile,'buffer'=>$bytearray)); } catch(SoapFault $ex) { if($ex->faultcode == "HTTP") { $error = "RIO -> FREO API Error field:$fld operation: $func - faultcode: ".$ex->faultcode." faultstring: ".$ex->faultstring; $additionalmessage = "
Unexpected Network Communication received from FREO Servers while attempting to connect.
RIO and FREO Tech Support have been notified.
"; freosalesforceapi_error($apn, $sendfile,strlen($filedata) ,$error, $client,$additionalmessage); //if we run into a connectivity issue, lets stop attempting to connect - return return $error; } return $ex; } $ret = array_shift($ret); dlog('freosalesforceapi',"$offer[propertyid] $offer[offerid] SOAPFUNC->Property_FileUpload(apn=>$apn,fileName=>$sendfile) (error=>'$ret->ErrorMsg', Succeeded=>'$ret->Succeeded' $property[propertyaddress])"); if(stristr($ret->ErrorMsg,'Property already has a file named')) //this means that the uload has already been done and we can ignore. return false; $r = (array)$ret; if ($r['ErrorMsg'] && strstr($r['ErrorMsg'],'DOCERROR:') ) { $additionalmessage = "
File Transfer Error received from FREO Servers while attempting to upload file: " . $sendfile . "
RIO and FREO Tech Support have been notified.
"; freosalesforceapi_error($apn, $sendfile,strlen($filedata) ,$r['ErrorMsg'], $client,$additionalmessage); return str_replace('DOCERROR:', '',$r['ErrorMsg']); // Return error } return false; } function freosalesforceapi_updatehoa($apn,$old,$newhoa){ return false; // Salesforce API disabled on Client Request MTX 21378 if (!$apn) return "Error: Missing APN"; // init SOAP global $soapwsdl; global $application_variables_set; d(glob,$application_variables_set); if(app_get('setting_freoapi_sandbox') || $_SESSION[developer][SOAP_SandBOX]) $soapwsdl = "http://4e598a44cdd3446288a316353ab9199a.cloudapp.net/riomsgprocessor.svc?wsdl"; // sandbox testing instance - use test apn: 54855 else $soapwsdl = "http://riomsgprocessor.cloudapp.net/riomsgprocessor.svc?wsdl"; //live site testing instance apn: 108xxx? d(wsdl,$soapwsdl); try { dlog('freosalesforceapi',"$apn $ SOAPCLIENT ($soapwsdl)"); ini_set("default_socket_timeout", 100); // this will extend SOAP socket to 100 sec $client = new SoapClient($soapwsdl, array('trace'=>1, "connection_timeout"=>100) ); } catch(Exception $ex) { d(ex,$ex); $error = "RIO -> FREO Connectivity Error - faultcode: ".$ex->faultcode." faultstring: ".$ex->faultstring; $additionalmessage = "
Unexpected Network Communication received from FREO Servers while attempting to connect.
RIO and FREO Tech Support have been notified.
"; freosalesforceapi_error($apn, 'oldhoa:'.$old.'new:'.$newhoa ,$error, $client,$additionalmessage); return "$error"; } if (1==2) { $fs = $client->__getFunctions(); $types =$client->__getTypes() ; d(freo_functions, $fs); d(freo_types, $types); d(property,$property); d(values,$values); } if (trim($old) !='' && $old !='N/A') { if (trim($newhoa) == 'N/A') $newhoa = ''; try { dlog('freosalesforceapi',"$apn SOAPFUNC->HoaUpdate_HoaName(apn=>$apn,value=>$newhoa,hoaName=>$old)"); $ret = (array) $client ->HoaUpdate_HoaName(array('apn'=>$apn,'value'=>$newhoa,'hoaName'=>$old)); } catch(SoapFault $ex) { if($ex->faultcode == "HTTP") { $error = "RIO -> FREO API Error HOA:$old operation: HOAUpdate - faultcode: ".$ex->faultcode." faultstring: ".$ex->faultstring; $additionalmessage = "
Unexpected Network Communication received from FREO Servers while attempting to connect.
RIO and FREO Tech Support have been notified.
"; freosalesforceapi_error($apn, $old,$newhoa ,$error, $client,$additionalmessage); //if we run into a connectivity issue, lets stop attempting to connect - return return $error; } return $ex; } }else if (trim($newhoa) !='N/A' && trim($newhoa) !=''){ // Per MB we are removing create code from this subroutine. Only update possible to prevent from creating duplicates on their end. // $createarr=array(); // $createarr[value] = $newhoa; // $createarr[apn] = $apn; // try // { // dlog('freosalesforceapi',"Hoa_Create $createarr[apn] '$createarr[value]'"); // $ret = $client->Hoa_Create($createarr); // d(createarr,$createarr); // d(ret,$ret); // } // catch(SoapFault $ex) // { // if($ex->faultcode == "HTTP") // { // $error = "RIO -> FREO API Error $ret = $client->Hoa_Create($createarr); operation: hoaCREATE - faultcode: ".$ex->faultcode." faultstring: ".$ex->faultstring; // freosalesforceapi_error($propdesc, $values[$uniquepe],$error,$createarr, $client); // //if we run into a connectivity issue, lets stop attempting to connect - return // return $error; // } // $error = "RIO -> FREO API Error field:$fld operation: $func - faultcode: ".$ex->faultcode." faultstring: ".$ex->faultstring; // freosalesforceapi_error($propdesc, $apn,$error,$createarr, $client); // continue; // } // if($ret->Hoa_CreateResult->ErrorMsg) // { // $error = "RIO -> FREO API Error Hoa_Create(".print_r($createarr,true)."); Error: ".$ret->Hoa_CreateResult->ErrorMsg; // freosalesforceapi_error($propdesc, $values[$uniquepe],$error,$createarr, $client); // //if we run into a connectivity issue, lets stop attempting to connect - return // return "HOA Did not save -> ".$ret->Hoa_CreateResult->ErrorMsg ; // } // Dont save new HOA return flase; } if (is_array($ret)) $ret = array_shift($ret); dlog('freosalesforceapi',"$apn SOAPFUNC->SOAPFUNC->HoaUpdate_HoaName(apn=>$apn,value=>$newhoa,hoaName=>$old) (error=>'$ret->ErrorMsg', Succeeded=>'$ret->Succeeded' )"); if(stristr($ret->ErrorMsg,'HOA')) return false; $r = (array)$ret; if ($r[ErrorMsg] && strstr($r[ErrorMsg],'HOA:') ) return str_replace('HOA:', '',$r[ErrorMsg]); // Return error return false; }