/** * Return updated url (current request url if provided url is null) with the provided query parms * @param string $url - optional - if not given the current request url will be used instead * @param array $query_parms - associative array or ready query string * @param bool $replace_query - replace current query completely (default is false which will result in merging the provided query parms with the parms in the url) * @return string */ public static function update_url($url = null, $query_parms, $replace_query = false) { if (!$url) { $request_url = SPUtils::url_from_parts(array("host" => $_SERVER["HTTP_HOST"], "scheme" => isset($_SERVER["HTTPS"]) ? "https" : "http", "port" => $_SERVER["SERVER_PORT"], "path" => $_SERVER["SCRIPT_NAME"])); $url_query_parms = $replace_query ? array() : $_GET; } else { $url_parts = parse_url($url); $url_query_parms = isset($url_parts['query']) && !$replace_query ? SPUtils::parse_query($url_parts['query']) : array(); $request_url = SPUtils::url_from_parts($url_parts); } $query_parms = is_array($query_parms) ? $query_parms : SPUtils::parse_query($query_parms); $query_parms = array_merge($url_query_parms, $query_parms); $query = ""; if ($query_parms) { $query = SPUtils::join_key_values_encode("=", "&", $query_parms); } return rtrim("{$request_url}?{$query}", "?"); }
public function handle_request($not_used = null, $not_used_ignore = null) { //! determine selected option for class $selected_option = ""; if (isset($_GET[ContactsHandler::$contacts_option])) { $selected_option = $_GET[ContactsHandler::$contacts_option]; } if (!$selected_option) { $this->error = true; } else { $this->session_start(); $state = $this->get_from_session($selected_option); $oauth_parms = array(); if ($state) { //! session data is stored as url encoded string, SPUtils::parse_query returns dictionary $oauth_parms = SPUtils::parse_query($state); } //! check if we have verifier, or if we already have access token in session //! either of these conditions means we already have user authorization (we get verifier back when the user is redirected back to external.php, and __oauth_access_token is set internally to indicate that the authorized request token has been already exchanged for a access token) if (isset($_GET[$this->response_parm]) || isset($oauth_parms["__oauth_access_token"])) { $this->response = true; } else { //! remove any previous request token (if any) from session and get another one //! assume previous token has been declined by the user or revoked already (by default the OAuth contacts importer classes, with the exception of Yahoo, make a call to revoke the access token as soon as the contacts data is retrieved, tokens may otherwise stay valid for long time) $this->remove_from_session($selected_option); //! see parent implementation - basically what happens there is instantiating the contacts importer class and attempting access to ->contacts, which would return null with error of "external authentication needed" + redirect url where we need to send the user to authorize our token //! another thing that happens behind the scenes when accessing ->contacts is getting a "request token" if we don't have a token already (and we wouldn't have a token on first request) //! External authentication/OAuth/API's usually are provided with limits, so request tokens in this examples are only acquired when the popup window is open (the other alternative is to get a request token on the main page and use the popup for redirect only) parent::handle_request(array("external" => "true")); if (!$this->redirect_url) { $this->error = true; } } } include_once "example/external.page.php"; }
/** * Execute a GET/POST request with the provided so far CURL options * @param $http_request_type GET/POST * @param $url * @param $data - for GET this should be assoc array, for POST a string or assoc array * @param $number_redirects * @return bool or response body */ public function execute_request($http_request_method, $url, $data = null, $number_redirects = 0) { if (strpos($url, "/") === 0) { $url = (isset($this->__request_url_parts["scheme"]) ? "{$this->__request_url_parts["scheme"]}://" : "http://") . $this->__request_url_parts["host"] . $url; } if (!preg_match("/^http/i", $url)) { $url = isset($this->__request_url_parts["scheme"]) ? "{$this->__request_url_parts["scheme"]}://{$url}" : "http://{$url}"; } $this->curl_error_text = ""; $this->curl_error_code = 0; $this->http_response_code = 0; $this->http_response_text = ""; $this->http_response_headers = array(array(), array()); $this->response_content_type = ""; $this->response_charset = ""; $this->http_response_body = ""; $this->__next_location = $url; $this->__request_url_parts = parse_url($url); $this->__request_query_parms = isset($this->__request_url_parts["query"]) ? SPUtils::parse_query($this->__request_url_parts["query"]) : array(); $http_request_method = strtoupper($http_request_method); if ($http_request_method == SPConstants::HTTP_METHOD_POST) { # for POST it will be assumed tha data is already in the necessary format (string for url encoded or associative array for multipart) $this->CURLOPT_POSTFIELDS = $data; } else { if ($http_request_method == SPConstants::HTTP_METHOD_GET) { $this->CURLOPT_HTTPGET = true; # if data is given, only associative array is expected with query parms to be updated/added to the current query if ($data && is_array($data) && $this->__request_query_parms) { $this->__request_query_parms = array_merge($this->__request_query_parms, $data); } else { if ($data && is_array($data)) { $this->__request_query_parms = $data; } } } else { //! else continue executing the request anyways, assume it is a custom method and if all curl options are set correctly it will be handled properly //! For PUT requests for example use write function callback (see php curl documentation) (do it directly on $this->__curl in a subclass set_request_options) $this->CURLOPT_HTTPGET = false; $this->CURLOPT_POST = false; } } if (!$this->__curl) { $this->__curl = curl_init(); } if ($this->__header_function) { curl_setopt($this->__curl, CURLOPT_HEADERFUNCTION, $this->__header_function); } $this->set_request_options(); $this->http_response_body = curl_exec($this->__curl); $this->CURLOPT_HTTPGET = true; # resetting post fields $this->http_response_location = $this->auto_redirect_curl ? curl_getinfo($this->__curl, CURLINFO_EFFECTIVE_URL) : $url; $this->http_response_code = curl_getinfo($this->__curl, CURLINFO_HTTP_CODE); $this->curl_error_code = curl_errno($this->__curl); $this->curl_error_text = curl_error($this->__curl); if ($this->curl_error_code) { return $this->return_response_body ? "" : false; } if ($this->__redirect && $this->auto_redirect && !$this->auto_redirect_curl && $number_redirects < $this->auto_redirect_max) { return $this->execute_request(SPConstants::HTTP_METHOD_GET, $this->__next_location, null, $number_redirects + 1); } $this->response_content_type = curl_getinfo($this->__curl, CURLINFO_CONTENT_TYPE); if ($this->response_content_type) { list($this->response_content_type, $charset) = explode(";", "{$this->response_content_type};"); if (preg_match("/charset=([^\\s;\$]+)/si", $charset, $matches)) { $this->response_charset = $matches[1]; } } return $this->return_response_body ? $this->http_response_body : $this->http_response_code == SPConstants::HTTP_OK; }
/** * This method assumes authentication has not happened previously * Parameters expected: email, password, captcha, extra (where extra is retrieved via GetState() after previous unsucessful attempt, optional or null otherwise) * @param string $email * @param string $password * @param string $captcha * @param string $extra */ public function Authenticate() { $loginparms = func_get_args(); if ($loginparms) { if (is_array(current($loginparms))) { $loginparms = array_shift($login_parms); } if (count($loginparms) > 3 && $loginparms[3]) { RestoreState($loginparms[3]); } if (count($loginparms) > 2 && $loginparms[2]) { $this->auth_parms["logincaptcha"] = $loginparms[2]; } if (count($loginparms) > 1 && $loginparms[1]) { $this->auth_parms["Passwd"] = $loginparms[1]; } if (count($loginparms) > 0 && $loginparms[0]) { $this->auth_parms["Email"] = $loginparms[0]; } } if (!$this->auth_parms["Email"] || !$this->auth_parms["Passwd"]) { $this->LoginResponse = GoogleAuthResponses::EmailPasswordMissing; return false; } $auth_string = SPUtils::join_key_values_encode("=", "&", $this->auth_parms); if (!$this->post(self::$login_url, $auth_string) && (!$this->http_response_code || !$this->http_response_body)) { $this->LoginResponse = GoogleAuthResponses::HTTPError; return false; } $response = SPUtils::parse_query(join("&", explode("\n", $this->http_response_body))); if ($auth = SPUtils::search_array($response, "auth")) { $this->auth_parms = $response; $this->auto_redirect_curl = false; $this->request_headers["Authorization"] = "GoogleLogin auth={$response[$auth]}"; return true; } $this->LoginResponse = isset($response["Error"]) ? $response["Error"] : GoogleAuthResponses::Unknown; $this->auth_parms["logintoken"] = isset($response['CaptchaToken']) ? $response['CaptchaToken'] : ""; $this->CaptchaUrl = self::$captcha_base_url . (isset($response['CaptchaUrl']) ? $response['CaptchaUrl'] : ""); return false; }
/** * Get a request/access token, returns true if successful (response body is in http_response_body) * Called internally from get_access_token/get_request_token * Parameters passed will be accepted in any given order, one bool, one string, if more given the last given will be used * @param string $url (access/request/other) token url * @param bool $auto_load_response, default is false, true when requesting access token * @return bool - returns true if response is HTTP 200 */ protected function get_token() { $args = func_get_args(); $url = ""; $auto_load_response = false; foreach ($args as $v) { if (is_string($v)) { $url = $v; continue; } if (is_bool($v)) { $auto_load_response = $v; continue; } } if (!$url) { trigger_error("Method get_token expects a url."); } $this->execute_request($this->auth_http_method == SPOAuthClient::HTTP_AUTH_HEADER ? SPOAuthClient::HTTP_AUTH_GET : $this->auth_http_method, $url); //! remove oauth_token and oauth_secret, they will be loaded (if any returned) in the next lines of code) $this->oauth_token = null; $this->oauth_token_secret = null; $this->__oauth_access_token = null; if ($auto_load_response && $this->http_response_code == SPConstants::HTTP_OK) { $response_data = SPUtils::parse_query($this->http_response_body); if (is_array($response_data)) { foreach ($response_data as $key => $value) { $this->__oauth[$key] = $value; } } } if ($this->http_response_code == SPConstants::HTTP_OK) { return true; } return false; }