├── spark.info ├── config └── autoload.php ├── libraries ├── Request │ ├── Credentials.php │ ├── Authorize.php │ ├── Resource.php │ ├── Access.php │ └── Token.php ├── Token │ ├── Access.php │ └── Request.php ├── Response.php ├── Provider │ ├── Dropbox.php │ ├── Twitter.php │ ├── Tumblr.php │ ├── Flickr.php │ ├── Linkedin.php │ └── Google.php ├── Consumer.php ├── Signature │ ├── Plaintext.php │ └── HMAC_SHA1.php ├── Signature.php ├── Token.php ├── Format.php ├── Provider.php ├── OAuth.php └── Request.php └── README.md /spark.info: -------------------------------------------------------------------------------- 1 | name: oauth 2 | version: 0.3.1 3 | compatibility: 2.1.1 -------------------------------------------------------------------------------- /config/autoload.php: -------------------------------------------------------------------------------- 1 | TRUE, 10 | ); 11 | 12 | public function execute(array $options = NULL) 13 | { 14 | return redirect($this->as_url()); 15 | } 16 | 17 | } // End Request_Authorize -------------------------------------------------------------------------------- /libraries/Request/Resource.php: -------------------------------------------------------------------------------- 1 | TRUE, 10 | 'oauth_token' => TRUE, 11 | 'oauth_signature_method' => TRUE, 12 | 'oauth_signature' => TRUE, 13 | 'oauth_timestamp' => TRUE, 14 | 'oauth_nonce' => TRUE, 15 | 'oauth_version' => TRUE, 16 | ); 17 | 18 | } // End Request_Resource -------------------------------------------------------------------------------- /libraries/Token/Request.php: -------------------------------------------------------------------------------- 1 | verifier($key); 16 | * 17 | * @param string new verifier 18 | * @return $this 19 | */ 20 | public function verifier($verifier) 21 | { 22 | $this->verifier = $verifier; 23 | 24 | return $this; 25 | } 26 | 27 | } // End Token_Request 28 | -------------------------------------------------------------------------------- /libraries/Request/Access.php: -------------------------------------------------------------------------------- 1 | TRUE, 9 | 'oauth_token' => TRUE, 10 | 'oauth_signature_method' => TRUE, 11 | 'oauth_signature' => TRUE, 12 | 'oauth_timestamp' => TRUE, 13 | 'oauth_nonce' => TRUE, 14 | // 'oauth_verifier' => TRUE, 15 | 'oauth_version' => TRUE, 16 | ); 17 | 18 | public function execute(array $options = NULL) 19 | { 20 | return new OAuth_Response(parent::execute($options)); 21 | } 22 | 23 | } // End Request_Access -------------------------------------------------------------------------------- /libraries/Request/Token.php: -------------------------------------------------------------------------------- 1 | TRUE, 10 | 'oauth_consumer_key' => TRUE, 11 | 'oauth_signature_method' => TRUE, 12 | 'oauth_signature' => TRUE, 13 | 'oauth_timestamp' => TRUE, 14 | 'oauth_nonce' => TRUE, 15 | 'oauth_version' => TRUE, 16 | ); 17 | 18 | 19 | public function execute(array $options = NULL) 20 | { 21 | return new OAuth_Response(parent::execute($options)); 22 | } 23 | 24 | } // End Request_Token -------------------------------------------------------------------------------- /libraries/Response.php: -------------------------------------------------------------------------------- 1 | params = OAuth::parse_params($body); 15 | } 16 | } 17 | 18 | /** 19 | * Return the value of any protected class variable. 20 | * 21 | * // Get the response parameters 22 | * $params = $response->params; 23 | * 24 | * @param string variable name 25 | * @return mixed 26 | */ 27 | public function __get($key) 28 | { 29 | return $this->$key; 30 | } 31 | 32 | public function param($name, $default = NULL) 33 | { 34 | return isset($this->params[$name]) ? $this->params[$name] : $default; 35 | } 36 | 37 | } // End Response 38 | -------------------------------------------------------------------------------- /libraries/Provider/Dropbox.php: -------------------------------------------------------------------------------- 1 | $consumer->key, 27 | 'oauth_token' => $token->access_token, 28 | )); 29 | 30 | // Sign the request using the consumer and token 31 | $request->sign($this->signature, $consumer, $token); 32 | 33 | $user = json_decode($request->execute()); 34 | 35 | // Create a response from the request 36 | return array( 37 | 'uid' => $token->uid, 38 | 'name' => $user->display_name, 39 | 'email' => $user->email, 40 | 'location' => $user->country, 41 | ); 42 | } 43 | 44 | } // End Provider_Dropbox -------------------------------------------------------------------------------- /libraries/Provider/Twitter.php: -------------------------------------------------------------------------------- 1 | $consumer->key, 29 | 'oauth_token' => $token->access_token, 30 | 'user_id' => $token->uid, 31 | )); 32 | 33 | // Sign the request using the consumer and token 34 | $request->sign($this->signature, $consumer, $token); 35 | 36 | $user = current(json_decode($request->execute())); 37 | 38 | // Create a response from the request 39 | return array( 40 | 'uid' => $token->uid, 41 | 'nickname' => $user->screen_name, 42 | 'name' => $user->name ? $user->name : $user->screen_name, 43 | 'location' => $user->location, 44 | 'image' => $user->profile_image_url, 45 | 'description' => $user->description, 46 | 'urls' => array( 47 | 'Website' => $user->url, 48 | 'Twitter' => 'http://twitter.com/'.$user->screen_name, 49 | ), 50 | ); 51 | } 52 | 53 | } // End Provider_Twitter 54 | -------------------------------------------------------------------------------- /libraries/Consumer.php: -------------------------------------------------------------------------------- 1 | key = $options['key']; 45 | 46 | $this->secret = $options['secret']; 47 | 48 | if (isset($options['callback'])) 49 | { 50 | $this->callback = $options['callback']; 51 | } 52 | 53 | if (isset($options['scope'])) 54 | { 55 | $this->scope = $options['scope']; 56 | } 57 | } 58 | 59 | /** 60 | * Return the value of any protected class variable. 61 | * 62 | * // Get the consumer key 63 | * $key = $consumer->key; 64 | * 65 | * @param string variable name 66 | * @return mixed 67 | */ 68 | public function __get($key) 69 | { 70 | return $this->$key; 71 | } 72 | 73 | /** 74 | * Change the consumer callback. 75 | * 76 | * @param string new consumer callback 77 | * @return $this 78 | */ 79 | public function callback($callback) 80 | { 81 | $this->callback = $callback; 82 | 83 | return $this; 84 | } 85 | 86 | } // End Consumer 87 | -------------------------------------------------------------------------------- /libraries/Provider/Tumblr.php: -------------------------------------------------------------------------------- 1 | . 7 | * 8 | * [!!] This class does not implement the Tumblr API. It is only an 9 | * implementation of standard OAuth with Tumblr as the service provider. 10 | * 11 | * @package OAuth 12 | * @category Provider 13 | * @author Fuel Development Team 14 | */ 15 | 16 | class OAuth_Provider_Tumblr extends OAuth_Provider { 17 | 18 | public $name = 'tumblr'; 19 | 20 | public function url_request_token() 21 | { 22 | return 'http://www.tumblr.com/oauth/request_token'; 23 | } 24 | 25 | public function url_authorize() 26 | { 27 | return 'http://www.tumblr.com/oauth/authorize'; 28 | } 29 | 30 | public function url_access_token() 31 | { 32 | return 'http://www.tumblr.com/oauth/access_token'; 33 | } 34 | 35 | public function get_user_info(OAuth_Consumer $consumer, OAuth_Token $token) 36 | { 37 | // Create a new GET request with the required parameters 38 | $request = OAuth_Request::forge('resource', 'GET', 'http://api.tumblr.com/v2/user/info', array( 39 | 'oauth_consumer_key' => $consumer->key, 40 | 'oauth_token' => $token->access_token, 41 | )); 42 | 43 | // Sign the request using the consumer and token 44 | $request->sign($this->signature, $consumer, $token); 45 | 46 | $response = json_decode($request->execute()); 47 | 48 | $status = current($response); 49 | $response = next($response); 50 | $user = $response->user; 51 | 52 | // Create a response from the request 53 | return array( 54 | 'uid' => $user->name, // Tumblr doesn't provide a unique key other than name 55 | 'name' => $user->name, 56 | 'likes' => $user->likes, 57 | 'following' => $user->following, 58 | 'default_post_format' => $user->default_post_format, 59 | ); 60 | } 61 | 62 | } // End Provider_Tumblr -------------------------------------------------------------------------------- /libraries/Provider/Flickr.php: -------------------------------------------------------------------------------- 1 | $consumer->key, 28 | 'oauth_token' => $token->access_token, 29 | 'nojsoncallback' => 1, 30 | 'format' => 'json', 31 | 'user_id' => $token->uid, 32 | 'method' => 'flickr.people.getInfo', 33 | )); 34 | 35 | // Sign the request using the consumer and token 36 | $request->sign($this->signature, $consumer, $token); 37 | 38 | $response = json_decode($request->execute(), true); 39 | $user = $response['person']; 40 | 41 | // Create a response from the request 42 | return array( 43 | 'uid' => $user['nsid'], 44 | 'name' => isset($user['realname']['_content']) ? $user['realname']['_content'] : $user['username']['_content'], 45 | 'nickname' => $user['username']['_content'], 46 | 'location' => isset($user['location']['_content']) ? $user['location']['_content'] : NULL, 47 | 'image' => $user['iconserver'] ? "http://farm{$user['iconfarm']}.staticflickr.com/{$user['iconserver']}/buddyicons/{$user['nsid']}.jpg" : NULL, 48 | 'urls' => array( 49 | 'photos' => $user['photosurl']['_content'], 50 | 'profile' => $user['profileurl']['_content'], 51 | ), 52 | ); 53 | } 54 | 55 | } // End Provider_Flickr -------------------------------------------------------------------------------- /libraries/Provider/Linkedin.php: -------------------------------------------------------------------------------- 1 | . 7 | * 8 | * [!!] This class does not implement the LinkedIn API. It is only an 9 | * implementation of standard OAuth with Twitter as the service provider. 10 | * 11 | */ 12 | 13 | class OAuth_Provider_Linkedin extends OAuth_Provider { 14 | 15 | public $name = 'linkedin'; 16 | 17 | public function url_request_token() 18 | { 19 | return 'https://api.linkedin.com/uas/oauth/requestToken'; 20 | } 21 | 22 | public function url_authorize() 23 | { 24 | return 'https://api.linkedin.com/uas/oauth/authorize'; 25 | } 26 | 27 | public function url_access_token() 28 | { 29 | return 'https://api.linkedin.com/uas/oauth/accessToken'; 30 | } 31 | 32 | public function get_user_info(OAuth_Consumer $consumer, OAuth_Token $token) 33 | { 34 | // Create a new GET request with the required parameters 35 | $url = 'https://api.linkedin.com/v1/people/~:(id,first-name,last-name,headline,member-url-resources,picture-url,location,public-profile-url)'; 36 | $request = OAuth_Request::forge('resource', 'GET', $url, array( 37 | 'oauth_consumer_key' => $consumer->key, 38 | 'oauth_token' => $token->access_token, 39 | )); 40 | 41 | // Sign the request using the consumer and token 42 | $request->sign($this->signature, $consumer, $token); 43 | 44 | $user = OAuth_Format::factory($request->execute(), 'xml')->to_array(); 45 | 46 | // Create a response from the request 47 | return array( 48 | 'uid' => $user['id'], 49 | 'name' => $user['first-name'].' '.$user['last-name'], 50 | 'nickname' => end(explode('/', $user['public-profile-url'])), 51 | 'description' => $user['headline'], 52 | 'location' => isset($user['location']['name']) ? $user['location']['name'] : null, 53 | 'urls' => array( 54 | 'Linked In' => $user['public-profile-url'], 55 | ), 56 | ); 57 | } 58 | 59 | } // End Provider_Dropbox -------------------------------------------------------------------------------- /libraries/Signature/Plaintext.php: -------------------------------------------------------------------------------- 1 | sign($request, $consumer, $token); 24 | * 25 | * [!!] This method implements [OAuth 1.0 Spec 9.4.1](http://oauth.net/core/1.0/#rfc.section.9.4.1). 26 | * 27 | * @param Request request 28 | * @param Consumer consumer 29 | * @param Token token 30 | * @return $this 31 | */ 32 | public function sign(Request $request, Consumer $consumer, Token $token = NULL) 33 | { 34 | // Use the signing key as the signature 35 | return $this->key($consumer, $token); 36 | } 37 | 38 | /** 39 | * Verify a plaintext signature. 40 | * 41 | * if ( ! $signature->verify($signature, $request, $consumer, $token)) 42 | * { 43 | * throw new Exception('Failed to verify signature'); 44 | * } 45 | * 46 | * [!!] This method implements [OAuth 1.0 Spec 9.4.2](http://oauth.net/core/1.0/#rfc.section.9.4.2). 47 | * 48 | * @param string signature to verify 49 | * @param Request request 50 | * @param Consumer consumer 51 | * @param Token token 52 | * @return boolean 53 | * @uses Signature_PLAINTEXT::sign 54 | */ 55 | public function verify($signature, Request $request, Consumer $consumer, Token $token = NULL) 56 | { 57 | return $signature === $this->key($consumer, $token); 58 | } 59 | 60 | } // End Signature_PLAINTEXT 61 | -------------------------------------------------------------------------------- /libraries/Signature.php: -------------------------------------------------------------------------------- 1 | name; 35 | * 36 | * @param string variable name 37 | * @return mixed 38 | */ 39 | public function __get($key) 40 | { 41 | return $this->$key; 42 | } 43 | 44 | /** 45 | * Get a signing key from a consumer and token. 46 | * 47 | * $key = $signature->key($consumer, $token); 48 | * 49 | * [!!] This method implements the signing key of [OAuth 1.0 Spec 9](http://oauth.net/core/1.0/#rfc.section.9). 50 | * 51 | * @param Consumer consumer 52 | * @param Token token 53 | * @return string 54 | * @uses OAuth::urlencode 55 | */ 56 | public function key(OAuth_Consumer $consumer, OAuth_Token $token = NULL) 57 | { 58 | $key = OAuth::urlencode($consumer->secret).'&'; 59 | 60 | if ($token) 61 | { 62 | $key .= OAuth::urlencode($token->secret); 63 | } 64 | 65 | return $key; 66 | } 67 | 68 | abstract public function sign(OAuth_Request $request, OAuth_Consumer $consumer, OAuth_Token $token = NULL); 69 | 70 | abstract public function verify($signature, OAuth_Request $request, OAuth_Consumer $consumer, OAuth_Token $token = NULL); 71 | 72 | } // End Signature 73 | -------------------------------------------------------------------------------- /libraries/Signature/HMAC_SHA1.php: -------------------------------------------------------------------------------- 1 | sign($request, $consumer, $token); 19 | * 20 | * [!!] This method implements [OAuth 1.0 Spec 9.2.1](http://oauth.net/core/1.0/#rfc.section.9.2.1). 21 | * 22 | * @param Request request 23 | * @param Consumer consumer 24 | * @param Token token 25 | * @return string 26 | * @uses Signature::key 27 | * @uses Request::base_string 28 | */ 29 | public function sign(OAuth_Request $request, OAuth_Consumer $consumer, OAuth_Token $token = NULL) 30 | { 31 | // Get the signing key 32 | $key = $this->key($consumer, $token); 33 | 34 | // Get the base string for the signature 35 | $base_string = $request->base_string(); 36 | 37 | // Sign the base string using the key 38 | return base64_encode(hash_hmac('sha1', $base_string, $key, TRUE)); 39 | } 40 | 41 | /** 42 | * Verify a HMAC-SHA1 signature. 43 | * 44 | * if ( ! $signature->verify($signature, $request, $consumer, $token)) 45 | * { 46 | * throw new Exception('Failed to verify signature'); 47 | * } 48 | * 49 | * [!!] This method implements [OAuth 1.0 Spec 9.2.2](http://oauth.net/core/1.0/#rfc.section.9.2.2). 50 | * 51 | * @param string signature to verify 52 | * @param Request request 53 | * @param Consumer consumer 54 | * @param Token token 55 | * @return boolean 56 | * @uses Signature_HMAC_SHA1::sign 57 | */ 58 | public function verify($signature, OAuth_Request $request, OAuth_Consumer $consumer, OAuth_Token $token = NULL) 59 | { 60 | return $signature === $this->sign($request, $consumer, $token); 61 | } 62 | 63 | } // End Signature_HMAC_SHA1 64 | -------------------------------------------------------------------------------- /libraries/Provider/Google.php: -------------------------------------------------------------------------------- 1 | $consumer->key, 48 | 'oauth_token' => $token->access_token, 49 | )); 50 | 51 | // Sign the request using the consumer and token 52 | $request->sign($this->signature, $consumer, $token); 53 | 54 | $response = json_decode($request->execute(), true); 55 | 56 | // Fetch data parts 57 | $email = \Arr::get($response, 'feed.id.$t'); 58 | $name = \Arr::get($response, 'feed.author.0.name.$t'); 59 | $name == '(unknown)' and $name = $email; 60 | 61 | return array( 62 | 'uid' => $email, 63 | 'nickname' => \Inflector::friendly_title($name), 64 | 'name' => $name, 65 | 'email' => $email, 66 | 'location' => null, 67 | 'image' => null, 68 | 'description' => null, 69 | 'urls' => array(), 70 | ); 71 | } 72 | 73 | } // End Provider_Gmail -------------------------------------------------------------------------------- /libraries/Token.php: -------------------------------------------------------------------------------- 1 | access_token = $options['access_token']; 64 | 65 | $this->secret = $options['secret']; 66 | 67 | // If we have a uid lets use it 68 | isset($options['uid']) and $this->uid = $options['uid']; 69 | } 70 | 71 | /** 72 | * Return the value of any protected class variable. 73 | * 74 | * // Get the token secret 75 | * $secret = $token->secret; 76 | * 77 | * @param string variable name 78 | * @return mixed 79 | */ 80 | public function __get($key) 81 | { 82 | return isset($this->$key) ? $this->$key : null; 83 | } 84 | 85 | /** 86 | * Return a boolean if the property is set 87 | * 88 | * // Get the token secret 89 | * if ($token->secret) exit('YAY SECRET'); 90 | * 91 | * @param string variable name 92 | * @return bool 93 | */ 94 | public function __isset($key) 95 | { 96 | return isset($this->$key); 97 | } 98 | 99 | /** 100 | * Returns the token key. 101 | * 102 | * @return string 103 | */ 104 | public function __toString() 105 | { 106 | return (string) $this->access_token; 107 | } 108 | 109 | } // End Token 110 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## CodeIgniter OAuth 2 | 3 | ## !!! DEPRECATED !!! 4 | **This package is no longer actively maintained. If somebody sends in a pull request with some major security bug 5 | then I'll merge it, but otherwise nothing will be done. Use [thephpleague/oauth1-client](https://github.com/thephpleague/oauth1-client) instead.** 6 | 7 | An implementation of the [OAuth](http://oauth.net/) protocol with drivers to work with different providers such as Twitter, Google, etc. 8 | 9 | This is based on the wonderful [Kohana OAuth](https://github.com/kohana/oauth) package but has been adapted to work with a wider range of providers. 10 | 11 | Note that this Spark ONLY provides the authorization mechanism. You will need to implement the example code below so you can save this information to make API requests on the users behalf. 12 | 13 | ### Providers 14 | 15 | - Dropbox 16 | - Flickr 17 | - Google 18 | - LinkedIn 19 | - Tumblr 20 | - Twitter 21 | 22 | ### Installation 23 | 24 | #### Install with Sparks 25 | 26 | ```console 27 | $ php tools/spark install -v0.3.1 oauth 28 | ``` 29 | 30 | ### Usage Example 31 | 32 | This example will need the user to go to a certain URL, which will support multiple providers. I like to set a controller to handle it and either have one single "session" method - or have another method for callbacks if you want to separate out the code even more. 33 | 34 | Here you'll see we have the provider passed in as a URI segment of "twitter" which can be used to find config in a database, or in a config multi-dimensional array. If you want to hard code it all then that is just fine too. 35 | 36 | Send your user to `http://example.com/auth/oauth/twitter` where Auth is the name of the controller. This will also be the address of the "Callback URL" which will be required by many OAuth providers. 37 | 38 | ```php 39 | class Auth extends CI_Controller 40 | { 41 | public function oauth($provider) 42 | { 43 | $this->load->helper('url'); 44 | 45 | $this->load->spark('oauth/0.3.1'); 46 | 47 | // Create an consumer from the config 48 | $consumer = $this->oauth->consumer(array( 49 | 'key' => $config['key'], 50 | 'secret' => $config['secret'], 51 | )); 52 | 53 | // Load the provider 54 | $provider = $this->oauth->provider($provider); 55 | 56 | // Create the URL to return the user to 57 | $callback = site_url('auth/oauth/'.$provider->name); 58 | 59 | if ( ! $this->input->get_post('oauth_token')) 60 | { 61 | // Add the callback URL to the consumer 62 | $consumer->callback($callback); 63 | 64 | // Get a request token for the consumer 65 | $token = $provider->request_token($consumer); 66 | 67 | // Store the token 68 | $this->session->set_userdata('oauth_token', base64_encode(serialize($token))); 69 | 70 | // Get the URL to the twitter login page 71 | $url = $provider->authorize($token, array( 72 | 'oauth_callback' => $callback, 73 | )); 74 | 75 | // Send the user off to login 76 | redirect($url); 77 | } 78 | else 79 | { 80 | if ($this->session->userdata('oauth_token')) 81 | { 82 | // Get the token from storage 83 | $token = unserialize(base64_decode($this->session->userdata('oauth_token'))); 84 | } 85 | 86 | if ( ! empty($token) AND $token->access_token !== $this->input->get_post('oauth_token')) 87 | { 88 | // Delete the token, it is not valid 89 | $this->session->unset_userdata('oauth_token'); 90 | 91 | // Send the user back to the beginning 92 | exit('invalid token after coming back to site'); 93 | } 94 | 95 | // Get the verifier 96 | $verifier = $this->input->get_post('oauth_verifier'); 97 | 98 | // Store the verifier in the token 99 | $token->verifier($verifier); 100 | 101 | // Exchange the request token for an access token 102 | $token = $provider->access_token($consumer, $token); 103 | 104 | // We got the token, let's get some user data 105 | $user = $provider->get_user_info($consumer, $token); 106 | 107 | // Here you should use this information to A) look for a user B) help a new user sign up with existing data. 108 | // If you store it all in a cookie and redirect to a registration page this is crazy-simple. 109 | echo "
Tokens: ";
110 | var_dump($token).PHP_EOL.PHP_EOL;
111 |
112 | echo "User Info: ";
113 | var_dump($user);
114 | }
115 | }
116 | }
117 | ```
118 |
119 | If all goes well you should see a dump of user data and have `$token` available. If all does not go well you'll likely have a bunch of errors on your screen.
120 |
--------------------------------------------------------------------------------
/libraries/Format.php:
--------------------------------------------------------------------------------
1 | format->factory(array('foo' => 'bar'))->to_xml();
22 | *
23 | * @param mixed general date to be converted
24 | * @param string data format the file was provided in
25 | * @return Factory
26 | */
27 | public function factory($data, $from_type = null)
28 | {
29 | // Stupid stuff to emulate the "new static()" stuff in this libraries PHP 5.3 equivalent
30 | $class = __CLASS__;
31 | return new $class($data, $from_type);
32 | }
33 |
34 | /**
35 | * Do not use this directly, call factory()
36 | */
37 | public function __construct($data = null, $from_type = null)
38 | {
39 | get_instance()->load->helper('inflector');
40 |
41 | // If the provided data is already formatted we should probably convert it to an array
42 | if ($from_type !== null)
43 | {
44 | if (method_exists($this, '_from_' . $from_type))
45 | {
46 | $data = call_user_func(array($this, '_from_' . $from_type), $data);
47 | }
48 |
49 | else
50 | {
51 | throw new Exception('Format class does not support conversion from "' . $from_type . '".');
52 | }
53 | }
54 |
55 | $this->_data = $data;
56 | }
57 |
58 | // FORMATING OUTPUT ---------------------------------------------------------
59 |
60 | public function to_array($data = null)
61 | {
62 | // If not just null, but nothing is provided
63 | if ($data === null and ! func_num_args())
64 | {
65 | $data = $this->_data;
66 | }
67 |
68 | $array = array();
69 |
70 | foreach ((array) $data as $key => $value)
71 | {
72 | if (is_object($value) or is_array($value))
73 | {
74 | $array[$key] = $this->to_array($value);
75 | }
76 |
77 | else
78 | {
79 | $array[$key] = $value;
80 | }
81 | }
82 |
83 | return $array;
84 | }
85 |
86 | // Format XML for output
87 | public function to_xml($data = null, $structure = null, $basenode = 'xml')
88 | {
89 | if ($data === null and ! func_num_args())
90 | {
91 | $data = $this->_data;
92 | }
93 |
94 | // turn off compatibility mode as simple xml throws a wobbly if you don't.
95 | if (ini_get('zend.ze1_compatibility_mode') == 1)
96 | {
97 | ini_set('zend.ze1_compatibility_mode', 0);
98 | }
99 |
100 | if ($structure === null)
101 | {
102 | $structure = simplexml_load_string("<$basenode />");
103 | }
104 |
105 | // Force it to be something useful
106 | if ( ! is_array($data) AND ! is_object($data))
107 | {
108 | $data = (array) $data;
109 | }
110 |
111 | foreach ($data as $key => $value)
112 | {
113 |
114 | //change false/true to 0/1
115 | if(is_bool($value))
116 | {
117 | $value = (int) $value;
118 | }
119 |
120 | // no numeric keys in our xml please!
121 | if (is_numeric($key))
122 | {
123 | // make string key...
124 | $key = (singular($basenode) != $basenode) ? singular($basenode) : 'item';
125 | }
126 |
127 | // replace anything not alpha numeric
128 | $key = preg_replace('/[^a-z_\-0-9]/i', '', $key);
129 |
130 | // if there is another array found recursively call this function
131 | if (is_array($value) || is_object($value))
132 | {
133 | $node = $structure->addChild($key);
134 |
135 | // recursive call.
136 | $this->to_xml($value, $node, $key);
137 | }
138 |
139 | else
140 | {
141 | // add single node.
142 | $value = htmlspecialchars(html_entity_decode($value, ENT_QUOTES, 'UTF-8'), ENT_QUOTES, "UTF-8");
143 |
144 | $structure->addChild($key, $value);
145 | }
146 | }
147 |
148 | return $structure->asXML();
149 | }
150 |
151 | // Format HTML for output
152 | public function to_html()
153 | {
154 | $data = $this->_data;
155 |
156 | // Multi-dimensional array
157 | if (isset($data[0]) && is_array($data[0]))
158 | {
159 | $headings = array_keys($data[0]);
160 | }
161 |
162 | // Single array
163 | else
164 | {
165 | $headings = array_keys($data);
166 | $data = array($data);
167 | }
168 |
169 | $ci = get_instance();
170 | $ci->load->library('table');
171 |
172 | $ci->table->set_heading($headings);
173 |
174 | foreach ($data as &$row)
175 | {
176 | $ci->table->add_row($row);
177 | }
178 |
179 | return $ci->table->generate();
180 | }
181 |
182 | // Format CSV for output
183 | public function to_csv()
184 | {
185 | $data = $this->_data;
186 |
187 | // Multi-dimensional array
188 | if (isset($data[0]) && is_array($data[0]))
189 | {
190 | $headings = array_keys($data[0]);
191 | }
192 |
193 | // Single array
194 | else
195 | {
196 | $headings = array_keys($data);
197 | $data = array($data);
198 | }
199 |
200 | $output = implode(',', $headings).PHP_EOL;
201 | foreach ($data as &$row)
202 | {
203 | $output .= '"'.implode('","', $row).'"'.PHP_EOL;
204 | }
205 |
206 | return $output;
207 | }
208 |
209 | // Encode as JSON
210 | public function to_json()
211 | {
212 | return json_encode($this->_data);
213 | }
214 |
215 | // Encode as Serialized array
216 | public function to_serialized()
217 | {
218 | return serialize($this->_data);
219 | }
220 |
221 | // Output as a string representing the PHP structure
222 | public function to_php()
223 | {
224 | return var_export($this->_data, TRUE);
225 | }
226 |
227 | // Format XML for output
228 | protected function _from_xml($string)
229 | {
230 | return $string ? (array) simplexml_load_string($string, 'SimpleXMLElement', LIBXML_NOCDATA) : array();
231 | }
232 |
233 | // Format CSV for output
234 | // This function is DODGY! Not perfect CSV support but works with my REST_Controller
235 | protected function _from_csv($string)
236 | {
237 | $data = array();
238 |
239 | // Splits
240 | $rows = explode("\n", trim($string));
241 | $headings = explode(',', array_shift($rows));
242 | foreach ($rows as $row)
243 | {
244 | // The substr removes " from start and end
245 | $data_fields = explode('","', trim(substr($row, 1, -1)));
246 |
247 | if (count($data_fields) == count($headings))
248 | {
249 | $data[] = array_combine($headings, $data_fields);
250 | }
251 | }
252 |
253 | return $data;
254 | }
255 |
256 | // Encode as JSON
257 | private function _from_json($string)
258 | {
259 | return json_decode(trim($string));
260 | }
261 |
262 | // Encode as Serialized array
263 | private function _from_serialize($string)
264 | {
265 | return unserialize(trim($string));
266 | }
267 |
268 | }
269 |
270 | /* End of file format.php */
--------------------------------------------------------------------------------
/libraries/Provider.php:
--------------------------------------------------------------------------------
1 | signature = $options['signature'];
57 | }
58 |
59 | if ( ! is_object($this->signature))
60 | {
61 | // Convert the signature name into an object
62 | $this->signature = OAuth_Signature::forge($this->signature);
63 | }
64 |
65 | if ( ! $this->name)
66 | {
67 | // Attempt to guess the name from the class name
68 | $this->name = strtolower(substr(get_class($this), strlen('Provider_')));
69 | }
70 | }
71 |
72 | /**
73 | * Return the value of any protected class variable.
74 | *
75 | * // Get the provider signature
76 | * $signature = $provider->signature;
77 | *
78 | * @param string variable name
79 | * @return mixed
80 | */
81 | public function __get($key)
82 | {
83 | return $this->$key;
84 | }
85 |
86 | /**
87 | * Returns the request token URL for the provider.
88 | *
89 | * $url = $provider->url_request_token();
90 | *
91 | * @return string
92 | */
93 | abstract public function url_request_token();
94 |
95 | /**
96 | * Returns the authorization URL for the provider.
97 | *
98 | * $url = $provider->url_authorize();
99 | *
100 | * @return string
101 | */
102 | abstract public function url_authorize();
103 |
104 | /**
105 | * Returns the access token endpoint for the provider.
106 | *
107 | * $url = $provider->url_access_token();
108 | *
109 | * @return string
110 | */
111 | abstract public function url_access_token();
112 |
113 | /**
114 | * Returns basic information about the user.
115 | *
116 | * $url = $provider->get_user_info();
117 | *
118 | * @return string
119 | */
120 | abstract public function get_user_info(OAuth_Consumer $consumer, OAuth_Token $token);
121 |
122 | /**
123 | * Ask for a request token from the OAuth provider.
124 | *
125 | * $token = $provider->request_token($consumer);
126 | *
127 | * @param Consumer consumer
128 | * @param array additional request parameters
129 | * @return Token_Request
130 | * @uses Request_Token
131 | */
132 | public function request_token(OAuth_Consumer $consumer, array $params = NULL)
133 | {
134 | // Create a new GET request for a request token with the required parameters
135 | $request = OAuth_Request::forge('token', 'GET', $this->url_request_token(), array(
136 | 'oauth_consumer_key' => $consumer->key,
137 | 'oauth_callback' => $consumer->callback,
138 | 'scope' => is_array($consumer->scope) ? implode($this->scope_seperator, $consumer->scope) : $consumer->scope,
139 | ));
140 |
141 | if ($params)
142 | {
143 | // Load user parameters
144 | $request->params($params);
145 | }
146 |
147 | // Sign the request using only the consumer, no token is available yet
148 | $request->sign($this->signature, $consumer);
149 |
150 | // Create a response from the request
151 | $response = $request->execute();
152 |
153 | // Store this token somewhere useful
154 | return OAuth_Token::forge('request', array(
155 | 'access_token' => $response->param('oauth_token'),
156 | 'secret' => $response->param('oauth_token_secret'),
157 | ));
158 | }
159 |
160 | /**
161 | * Get the authorization URL for the request token.
162 | *
163 | * Response::redirect($provider->authorize_url($token));
164 | *
165 | * @param Token_Request token
166 | * @param array additional request parameters
167 | * @return string
168 | */
169 | public function authorize(OAuth_Token_Request $token, array $params = NULL)
170 | {
171 | // Create a new GET request for a request token with the required parameters
172 | $request = OAuth_Request::forge('authorize', 'GET', $this->url_authorize(), array(
173 | 'oauth_token' => $token->access_token,
174 | ));
175 |
176 | if ($params)
177 | {
178 | // Load user parameters
179 | $request->params($params);
180 | }
181 |
182 | return $request->as_url();
183 | }
184 |
185 | /**
186 | * Exchange the request token for an access token.
187 | *
188 | * $token = $provider->access_token($consumer, $token);
189 | *
190 | * @param Consumer consumer
191 | * @param Token_Request token
192 | * @param array additional request parameters
193 | * @return Token_Access
194 | */
195 | public function access_token(OAuth_Consumer $consumer, OAuth_Token_Request $token, array $params = NULL)
196 | {
197 | // Create a new GET request for a request token with the required parameters
198 | $request = OAuth_Request::forge('access', 'GET', $this->url_access_token(), array(
199 | 'oauth_consumer_key' => $consumer->key,
200 | 'oauth_token' => $token->access_token,
201 | 'oauth_verifier' => $token->verifier,
202 | ));
203 |
204 | if ($params)
205 | {
206 | // Load user parameters
207 | $request->params($params);
208 | }
209 |
210 | // Sign the request using only the consumer, no token is available yet
211 | $request->sign($this->signature, $consumer, $token);
212 |
213 | // Create a response from the request
214 | $response = $request->execute();
215 |
216 | // Store this token somewhere useful
217 | return OAuth_Token::forge('access', array(
218 | 'access_token' => $response->param('oauth_token'),
219 | 'secret' => $response->param('oauth_token_secret'),
220 | 'uid' => $response->param($this->uid_key) ? $response->param($this->uid_key) : get_instance()->input->get_post($this->uid_key),
221 | ));
222 | }
223 |
224 | } // End Provider
--------------------------------------------------------------------------------
/libraries/OAuth.php:
--------------------------------------------------------------------------------
1 | TRUE,
46 | * CURLOPT_POSTFIELDS => http_build_query($array),
47 | * ));
48 | *
49 | * @param string remote URL
50 | * @param array curl options
51 | * @return string
52 | * @throws Exception
53 | */
54 | public static function remote($url, array $options = NULL)
55 | {
56 | // The transfer must always be returned
57 | $options[CURLOPT_RETURNTRANSFER] = TRUE;
58 |
59 | // Open a new remote connection
60 | $remote = curl_init($url);
61 |
62 | // Set connection options
63 | if ( ! curl_setopt_array($remote, $options))
64 | {
65 | throw new Exception('Failed to set CURL options, check CURL documentation: http://php.net/curl_setopt_array');
66 | }
67 |
68 | // Get the response
69 | $response = curl_exec($remote);
70 |
71 | // Get the response information
72 | $code = curl_getinfo($remote, CURLINFO_HTTP_CODE);
73 |
74 | if ($code AND ($code < 200 OR $code > 299))
75 | {
76 | $error = $response;
77 | }
78 | elseif ($response === FALSE)
79 | {
80 | $error = curl_error($remote);
81 | }
82 |
83 | // Close the connection
84 | curl_close($remote);
85 |
86 | if (isset($error))
87 | {
88 | throw new Exception(sprintf('Error fetching remote %s [ status %s ] %s', $url, $code, $error));
89 | }
90 |
91 | return $response;
92 | }
93 | /**
94 | * RFC3986 compatible version of urlencode. Passing an array will encode
95 | * all of the values in the array. Array keys will not be encoded.
96 | *
97 | * $input = OAuth::urlencode($input);
98 | *
99 | * Multi-dimensional arrays are not allowed!
100 | *
101 | * [!!] This method implements [OAuth 1.0 Spec 5.1](http://oauth.net/core/1.0/#rfc.section.5.1).
102 | *
103 | * @param mixed input string or array
104 | * @return mixed
105 | */
106 | public static function urlencode($input)
107 | {
108 | if (is_array($input))
109 | {
110 | // Encode the values of the array
111 | return array_map(array('OAuth', 'urlencode'), $input);
112 | }
113 |
114 | // Encode the input
115 | $input = rawurlencode($input);
116 |
117 | return $input;
118 | }
119 |
120 | /**
121 | * RFC3986 complaint version of urldecode. Passing an array will decode
122 | * all of the values in the array. Array keys will not be encoded.
123 | *
124 | * $input = OAuth::urldecode($input);
125 | *
126 | * Multi-dimensional arrays are not allowed!
127 | *
128 | * [!!] This method implements [OAuth 1.0 Spec 5.1](http://oauth.net/core/1.0/#rfc.section.5.1).
129 | *
130 | * @param mixed input string or array
131 | * @return mixed
132 | */
133 | public static function urldecode($input)
134 | {
135 | if (is_array($input))
136 | {
137 | // Decode the values of the array
138 | return array_map(array('OAuth', 'urldecode'), $input);
139 | }
140 |
141 | // Decode the input
142 | return rawurldecode($input);
143 | }
144 |
145 | /**
146 | * Normalize all request parameters into a string.
147 | *
148 | * $query = OAuth::normalize_params($params);
149 | *
150 | * [!!] This method implements [OAuth 1.0 Spec 9.1.1](http://oauth.net/core/1.0/#rfc.section.9.1.1).
151 | *
152 | * @param array request parameters
153 | * @return string
154 | * @uses OAuth::urlencode
155 | */
156 | public static function normalize_params(array $params = NULL)
157 | {
158 | if ( ! $params)
159 | {
160 | // Nothing to do
161 | return '';
162 | }
163 |
164 | // Encode the parameter keys and values
165 | $keys = OAuth::urlencode(array_keys($params));
166 | $values = OAuth::urlencode(array_values($params));
167 |
168 | // Recombine the parameters
169 | $params = array_combine($keys, $values);
170 |
171 | // OAuth Spec 9.1.1 (1)
172 | // "Parameters are sorted by name, using lexicographical byte value ordering."
173 | uksort($params, 'strcmp');
174 |
175 | // Create a new query string
176 | $query = array();
177 |
178 | foreach ($params as $name => $value)
179 | {
180 | if (is_array($value))
181 | {
182 | // OAuth Spec 9.1.1 (1)
183 | // "If two or more parameters share the same name, they are sorted by their value."
184 | $value = natsort($value);
185 |
186 | foreach ($value as $duplicate)
187 | {
188 | $query[] = $name.'='.$duplicate;
189 | }
190 | }
191 | else
192 | {
193 | $query[] = $name.'='.$value;
194 | }
195 | }
196 |
197 | return implode('&', $query);
198 | }
199 |
200 | /**
201 | * Parse the query string out of the URL and return it as parameters.
202 | * All GET parameters must be removed from the request URL when building
203 | * the base string and added to the request parameters.
204 | *
205 | * // parsed parameters: array('oauth_key' => 'abcdef123456789')
206 | * list($url, $params) = OAuth::parse_url('http://example.com/oauth/access?oauth_key=abcdef123456789');
207 | *
208 | * [!!] This implements [OAuth Spec 9.1.1](http://oauth.net/core/1.0/#rfc.section.9.1.1).
209 | *
210 | * @param string URL to parse
211 | * @return array (clean_url, params)
212 | * @uses OAuth::parse_params
213 | */
214 | public static function parse_url($url)
215 | {
216 | if ($query = parse_url($url, PHP_URL_QUERY))
217 | {
218 | // Remove the query string from the URL
219 | list($url) = explode('?', $url, 2);
220 |
221 | // Parse the query string as request parameters
222 | $params = OAuth::parse_params($query);
223 | }
224 | else
225 | {
226 | // No parameters are present
227 | $params = array();
228 | }
229 |
230 | return array($url, $params);
231 | }
232 |
233 | /**
234 | * Parse the parameters in a string and return an array. Duplicates are
235 | * converted into indexed arrays.
236 | *
237 | * // Parsed: array('a' => '1', 'b' => '2', 'c' => '3')
238 | * $params = OAuth::parse_params('a=1,b=2,c=3');
239 | *
240 | * // Parsed: array('a' => array('1', '2'), 'c' => '3')
241 | * $params = OAuth::parse_params('a=1,a=2,c=3');
242 | *
243 | * @param string parameter string
244 | * @return array
245 | */
246 | public static function parse_params($params)
247 | {
248 | // Split the parameters by &
249 | $params = explode('&', trim($params));
250 |
251 | // Create an array of parsed parameters
252 | $parsed = array();
253 |
254 | foreach ($params as $param)
255 | {
256 | // Split the parameter into name and value
257 | list($name, $value) = explode('=', $param, 2);
258 |
259 | // Decode the name and value
260 | $name = OAuth::urldecode($name);
261 | $value = OAuth::urldecode($value);
262 |
263 | if (isset($parsed[$name]))
264 | {
265 | if ( ! is_array($parsed[$name]))
266 | {
267 | // Convert the parameter to an array
268 | $parsed[$name] = array($parsed[$name]);
269 | }
270 |
271 | // Add a new duplicate parameter
272 | $parsed[$name][] = $value;
273 | }
274 | else
275 | {
276 | // Add a new parameter
277 | $parsed[$name] = $value;
278 | }
279 | }
280 |
281 | return $parsed;
282 | }
283 |
284 | } // End OAuth
285 |
--------------------------------------------------------------------------------
/libraries/Request.php:
--------------------------------------------------------------------------------
1 | method = strtoupper($method);
81 | }
82 |
83 | // Separate the URL and query string, which will be used as additional
84 | // default parameters
85 | list ($url, $default) = OAuth::parse_url($url);
86 |
87 | // Set the request URL
88 | $this->url = $url;
89 |
90 | if ($default)
91 | {
92 | // Set the default parameters
93 | $this->params($default);
94 | }
95 |
96 | if ($params)
97 | {
98 | // Set the request parameters
99 | $this->params($params);
100 | }
101 |
102 | if ($this->required('oauth_version') AND ! isset($this->params['oauth_version']))
103 | {
104 | // Set the version of this request
105 | $this->params['oauth_version'] = OAuth::$version;
106 | }
107 |
108 | if ($this->required('oauth_timestamp') AND ! isset($this->params['oauth_timestamp']))
109 | {
110 | // Set the timestamp of this request
111 | $this->params['oauth_timestamp'] = $this->timestamp();
112 | }
113 |
114 | if ($this->required('oauth_nonce') AND ! isset($this->params['oauth_nonce']))
115 | {
116 | // Set the unique nonce of this request
117 | $this->params['oauth_nonce'] = $this->nonce();
118 | }
119 | }
120 |
121 | /**
122 | * Return the value of any protected class variable.
123 | *
124 | * // Get the request parameters
125 | * $params = $request->params;
126 | *
127 | * // Get the request URL
128 | * $url = $request->url;
129 | *
130 | * @param string variable name
131 | * @return mixed
132 | */
133 | public function __get($key)
134 | {
135 | return $this->$key;
136 | }
137 |
138 | /**
139 | * Generates the UNIX timestamp for a request.
140 | *
141 | * $time = $request->timestamp();
142 | *
143 | * [!!] This method implements [OAuth 1.0 Spec 8](http://oauth.net/core/1.0/#rfc.section.8).
144 | *
145 | * @return integer
146 | */
147 | public function timestamp()
148 | {
149 | return time();
150 | }
151 |
152 | /**
153 | * Generates the nonce for a request.
154 | *
155 | * $nonce = $request->nonce();
156 | *
157 | * [!!] This method implements [OAuth 1.0 Spec 8](http://oauth.net/core/1.0/#rfc.section.8).
158 | *
159 | * @return string
160 | * @uses Text::random
161 | */
162 | public function nonce()
163 | {
164 | get_instance()->load->helper('string');
165 | return random_string('alnum', 40);
166 | }
167 |
168 | /**
169 | * Get the base signature string for a request.
170 | *
171 | * $base = $request->base_string();
172 | *
173 | * [!!] This method implements [OAuth 1.0 Spec A5.1](http://oauth.net/core/1.0/#rfc.section.A.5.1).
174 | *
175 | * @param Request request to sign
176 | * @return string
177 | * @uses OAuth::urlencode
178 | * @uses OAuth::normalize_params
179 | */
180 | public function base_string()
181 | {
182 | $url = $this->url;
183 |
184 | // Get the request parameters
185 | $params = array_diff_key($this->params, $this->upload);
186 |
187 | // "oauth_signature" is never included in the base string!
188 | unset($params['oauth_signature']);
189 |
190 | // method & url & sorted-parameters
191 | return implode('&', array(
192 | $this->method,
193 | OAuth::urlencode($url),
194 | OAuth::urlencode(OAuth::normalize_params($params)),
195 | ));
196 | }
197 |
198 | /**
199 | * Parameter getter and setter. Setting the value to `NULL` will remove it.
200 | *
201 | * // Set the "oauth_consumer_key" to a new value
202 | * $request->param('oauth_consumer_key', $key);
203 | *
204 | * // Get the "oauth_consumer_key" value
205 | * $key = $request->param('oauth_consumer_key');
206 | *
207 | * @param string parameter name
208 | * @param mixed parameter value
209 | * @param boolean allow duplicates?
210 | * @return mixed when getting
211 | * @return $this when setting
212 | * @uses Arr::get
213 | */
214 | public function param($name, $value = NULL, $duplicate = FALSE)
215 | {
216 | if ($value === NULL)
217 | {
218 | // Get the parameter
219 | return isset($this->params[$name]) ? $this->params[$name] : null;
220 | }
221 |
222 | if (isset($this->params[$name]) AND $duplicate)
223 | {
224 | if ( ! is_array($this->params[$name]))
225 | {
226 | // Convert the parameter into an array
227 | $this->params[$name] = array($this->params[$name]);
228 | }
229 |
230 | // Add the duplicate value
231 | $this->params[$name][] = $value;
232 | }
233 | else
234 | {
235 | // Set the parameter value
236 | $this->params[$name] = $value;
237 | }
238 |
239 | return $this;
240 | }
241 |
242 | /**
243 | * Set multiple parameters.
244 | *
245 | * $request->params($params);
246 | *
247 | * @param array parameters
248 | * @param boolean allow duplicates?
249 | * @return $this
250 | * @uses Request::param
251 | */
252 | public function params(array $params, $duplicate = FALSE)
253 | {
254 | foreach ($params as $name => $value)
255 | {
256 | $this->param($name, $value, $duplicate);
257 | }
258 |
259 | return $this;
260 | }
261 |
262 | /**
263 | * Upload getter and setter. Setting the value to `NULL` will remove it.
264 | *
265 | * // Set the "image" file path for uploading
266 | * $request->upload('image', $file_path);
267 | *
268 | * // Get the "image" file path
269 | * $key = $request->param('oauth_consumer_key');
270 | *
271 | * @param string upload name
272 | * @param mixed upload file path
273 | * @return mixed when getting
274 | * @return $this when setting
275 | * @uses Request::param
276 | */
277 | public function upload($name, $value = NULL)
278 | {
279 | if ($value !== NULL)
280 | {
281 | // This is an upload parameter
282 | $this->upload[$name] = TRUE;
283 |
284 | // Get the mime type of the image
285 | $mime = get_mime_by_extension($value);
286 |
287 | // Format the image path for CURL
288 | $value = "@{$value};type={$mime}";
289 | }
290 |
291 | return $this->param($name, $value, FALSE);
292 | }
293 |
294 | /**
295 | * Get and set required parameters.
296 | *
297 | * $request->required($field, $value);
298 | *
299 | * @param string parameter name
300 | * @param boolean field value
301 | * @return boolean when getting
302 | * @return $this when setting
303 | */
304 | public function required($param, $value = NULL)
305 | {
306 | if ($value === NULL)
307 | {
308 | // Get the current status
309 | return ! empty($this->required[$param]);
310 | }
311 |
312 | // Change the requirement value
313 | $this->required[$param] = (boolean) $value;
314 |
315 | return $this;
316 | }
317 |
318 | /**
319 | * Convert the request parameters into an `Authorization` header.
320 | *
321 | * $header = $request->as_header();
322 | *
323 | * [!!] This method implements [OAuth 1.0 Spec 5.4.1](http://oauth.net/core/1.0/#rfc.section.5.4.1).
324 | *
325 | * @return string
326 | */
327 | public function as_header()
328 | {
329 | $header = array();
330 |
331 | foreach ($this->params as $name => $value)
332 | {
333 | if (strpos($name, 'oauth_') === 0)
334 | {
335 | // OAuth Spec 5.4.1
336 | // "Parameter names and values are encoded per Parameter Encoding [RFC 3986]."
337 | $header[] = OAuth::urlencode($name).'="'.OAuth::urlencode($value).'"';
338 | }
339 | }
340 |
341 | return 'OAuth '.implode(', ', $header);
342 | }
343 |
344 | /**
345 | * Convert the request parameters into a query string, suitable for GET and
346 | * POST requests.
347 | *
348 | * $query = $request->as_query();
349 | *
350 | * [!!] This method implements [OAuth 1.0 Spec 5.2 (2,3)](http://oauth.net/core/1.0/#rfc.section.5.2).
351 | *
352 | * @param boolean include oauth parameters?
353 | * @param boolean return a normalized string?
354 | * @return string
355 | */
356 | public function as_query($include_oauth = NULL, $as_string = TRUE)
357 | {
358 | if ($include_oauth === NULL)
359 | {
360 | // If we are sending a header, OAuth parameters should not be
361 | // included in the query string.
362 | $include_oauth = ! $this->send_header;
363 | }
364 |
365 | if ($include_oauth)
366 | {
367 | $params = $this->params;
368 | }
369 | else
370 | {
371 | $params = array();
372 | foreach ($this->params as $name => $value)
373 | {
374 | if (strpos($name, 'oauth_') !== 0)
375 | {
376 | // This is not an OAuth parameter
377 | $params[$name] = $value;
378 | }
379 | }
380 | }
381 |
382 | return $as_string ? OAuth::normalize_params($params) : $params;
383 | }
384 |
385 | /**
386 | * Return the entire request URL with the parameters as a GET string.
387 | *
388 | * $url = $request->as_url();
389 | *
390 | * @return string
391 | * @uses Request::as_query
392 | */
393 | public function as_url()
394 | {
395 | return $this->url.'?'.$this->as_query(TRUE);
396 | }
397 |
398 | /**
399 | * Sign the request, setting the `oauth_signature_method` and `oauth_signature`.
400 | *
401 | * @param Signature signature
402 | * @param Consumer consumer
403 | * @param Token token
404 | * @return $this
405 | * @uses Signature::sign
406 | */
407 | public function sign(OAuth_Signature $signature, OAuth_Consumer $consumer, OAuth_Token $token = NULL)
408 | {
409 | // Create a new signature class from the method
410 | $this->param('oauth_signature_method', $signature->name);
411 |
412 | // Sign the request using the consumer and token
413 | $this->param('oauth_signature', $signature->sign($this, $consumer, $token));
414 |
415 | return $this;
416 | }
417 |
418 | /**
419 | * Checks that all required request parameters have been set. Throws an
420 | * exception if any parameters are missing.
421 | *
422 | * try
423 | * {
424 | * $request->check();
425 | * }
426 | * catch (Exception $e)
427 | * {
428 | * // Request has missing parameters
429 | * }
430 | *
431 | * @return TRUE
432 | * @throws Exception
433 | */
434 | public function check()
435 | {
436 | foreach ($this->required as $param => $required)
437 | {
438 | if ($required AND ! isset($this->params[$param]))
439 | {
440 | throw new Exception(sprintf('Request to %s requires missing parameter "%s"', $this->url, $param));
441 | }
442 | }
443 |
444 | return TRUE;
445 | }
446 |
447 | /**
448 | * Execute the request and return a response.
449 | *
450 | * @param array additional cURL options
451 | * @return string request response body
452 | * @uses Request::check
453 | * @uses Arr::get
454 | * @uses Remote::get
455 | */
456 | public function execute(array $options = NULL)
457 | {
458 | // Check that all required fields are set
459 | $this->check();
460 |
461 | // Get the URL of the request
462 | $url = $this->url;
463 |
464 | if ( ! isset($options[CURLOPT_CONNECTTIMEOUT]))
465 | {
466 | // Use the request default timeout
467 | $options[CURLOPT_CONNECTTIMEOUT] = $this->timeout;
468 | }
469 |
470 | if (ENVIRONMENT === 'development')
471 | {
472 | $options[CURLOPT_SSL_VERIFYPEER] = false;
473 | }
474 |
475 | if ($this->send_header)
476 | {
477 | // Get the the current headers
478 | $headers = isset($options[CURLOPT_HTTPHEADER]) ? $options[CURLOPT_HTTPHEADER] : array();
479 |
480 | // Add the Authorization header
481 | $headers[] = 'Authorization: '.$this->as_header();
482 |
483 | // Store the new headers
484 | $options[CURLOPT_HTTPHEADER] = $headers;
485 | }
486 |
487 | if ($this->method === 'POST')
488 | {
489 | // Send the request as a POST
490 | $options[CURLOPT_POST] = TRUE;
491 |
492 | if ($post = $this->as_query(NULL, empty($this->upload)))
493 | {
494 | // Attach the post fields to the request
495 | $options[CURLOPT_POSTFIELDS] = $post;
496 | }
497 | }
498 | elseif ($query = $this->as_query())
499 | {
500 | // Append the parameters to the query string
501 | $url = "{$url}?{$query}";
502 | }
503 |
504 | return OAuth::remote($url, $options);
505 | }
506 |
507 | } // End Request
508 |
--------------------------------------------------------------------------------