Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Adding support for multipart image uploads. It's 1/2 working.

  • Loading branch information...
commit 5fc33a53feaac0f533be2e7b0a02374540a04344 1 parent ea28b21
@jmathai authored
View
50 EpiOAuth.php
@@ -46,7 +46,7 @@ public function getUrl($url)
return $url;
}
- public function httpRequest($method = null, $url = null, $params = null)
+ public function httpRequest($method = null, $url = null, $params = null, $isMultipart = false)
{
if(empty($method) || empty($url))
return false;
@@ -60,7 +60,7 @@ public function httpRequest($method = null, $url = null, $params = null)
return $this->httpGet($url, $params);
break;
case 'POST':
- return $this->httpPost($url, $params);
+ return $this->httpPost($url, $params, $isMultipart);
break;
}
}
@@ -86,7 +86,6 @@ protected function addOAuthHeaders(&$ch, $url, $oauthHeaders)
$oauth .= "{$name}=\"{$value}\",";
}
$_h[] = substr($oauth, 0, -1);
-
curl_setopt($ch, CURLOPT_HTTPHEADER, $_h);
}
@@ -120,7 +119,6 @@ protected function generateSignature($method = null, $url = null, $params = null
if(empty($method) || empty($url))
return false;
-
// concatenating
$concatenatedParams = '';
foreach($params as $k => $v)
@@ -156,12 +154,17 @@ protected function httpGet($url, $params = null)
return $resp;
}
- protected function httpPost($url, $params = null)
+ protected function httpPost($url, $params = null, $isMultipart)
{
$ch = $this->curlInit($url);
$this->addOAuthHeaders($ch, $url, $params['oauth']);
curl_setopt($ch, CURLOPT_POST, 1);
- curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params['request']));
+ // php's curl extension automatically sets the content type
+ // based on whether the params are in string or array form
+ if($isMultipart)
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $params['request']);
+ else
+ curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params['request']));
$resp = $this->curl->addCurl($ch);
return $resp;
}
@@ -198,18 +201,39 @@ protected function prepareParameters($method = null, $url = null, $params = null
$oauth['oauth_timestamp'] = !isset($this->timestamp) ? time() : $this->timestamp; // for unit test
$oauth['oauth_signature_method'] = $this->signatureMethod;
$oauth['oauth_version'] = $this->version;
-
- // encoding
- array_walk($oauth, array($this, 'encode_rfc3986'));
+ // encode all oauth values
+// foreach($oauth as $k => $v)
+// $oauth[$k] = $this->encode_rfc3986($v);
+// // encode all non '@' params
+// // keep sigParams for signature generation (exclude '@' params)
+// // rename '@key' to 'key'
+// $sigParams = array();
if(is_array($params))
- array_walk($params, array($this, 'encode_rfc3986'));
- $encodedParams = array_merge($oauth, (array)$params);
+ {
+ foreach($params as $k => $v)
+ {
+ if(strncmp('@',$k,1) !== 0)
+ {
+// $sigParams[$k] = $this->encode_rfc3986($v);
+// $params[$k] = $this->encode_rfc3986($v);
+ $sigParams[$k] = ($v);
+ $params[$k] = ($v);
+ }
+ else
+ {
+ $params[substr($k, 1)] = $v;
+ unset($params[$k]);
+ }
+ }
+ }
+
+ $sigParams = array_merge($oauth, (array)$sigParams);
// sorting
- ksort($encodedParams);
+ ksort($sigParams);
// signing
- $oauth['oauth_signature'] = $this->encode_rfc3986($this->generateSignature($method, $url, $encodedParams));
+ $oauth['oauth_signature'] = $this->encode_rfc3986($this->generateSignature($method, $url, $sigParams));
return array('request' => $params, 'oauth' => $oauth);
}
View
45 EpiTwitter.php
@@ -12,6 +12,8 @@
class EpiTwitter extends EpiOAuth
{
const EPITWITTER_SIGNATURE_METHOD = 'HMAC-SHA1';
+ const EPITWITTER_AUTH_OAUTH = 'oauth';
+ const EPITWITTER_AUTH_BASIC = 'basic';
protected $requestTokenUrl= 'http://twitter.com/oauth/request_token';
protected $accessTokenUrl = 'http://twitter.com/oauth/access_token';
protected $authorizeUrl = 'http://twitter.com/oauth/authorize';
@@ -27,19 +29,34 @@ public function __call($name, $params = null)
$path = '/' . preg_replace('/[A-Z]|[0-9]+/e', "'/'.strtolower('\\0')", $parts) . '.json';
$args = !empty($params) ? array_shift($params) : null;
- // intercept calls to the search api
- if(preg_match('/^(search|trends)/', $parts))
+ // calls which do not have a consumerKey are assumed to not require authentication
+ if(empty($this->consumerKey))
{
+ echo 'do basic';
$query = isset($args) ? http_build_query($args) : '';
$url = "{$this->searchUrl}{$path}?{$query}";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- return new EpiTwitterJson(EpiCurl::getInstance()->addCurl($ch));
+ return new EpiTwitterJson(EpiCurl::getInstance()->addCurl($ch), self::EPITWITTER_AUTH_BASIC);
+ }
+
+ // parse the keys to determine if this should be multipart
+ $isMultipart = false;
+ if($args)
+ {
+ foreach($args as $k => $v)
+ {
+ if(strncmp('@',$k,1) === 0)
+ {
+ $isMultipart = true;
+ break;
+ }
+ }
}
$url = $this->getUrl("{$this->apiUrl}{$path}");
- return new EpiTwitterJson(call_user_func(array($this, 'httpRequest'), $method, $url, $args));
+ return new EpiTwitterJson(call_user_func(array($this, 'httpRequest'), $method, $url, $args, $isMultipart));
}
public function __construct($consumerKey = null, $consumerSecret = null, $oauthToken = null, $oauthTokenSecret = null)
@@ -52,9 +69,12 @@ public function __construct($consumerKey = null, $consumerSecret = null, $oauthT
class EpiTwitterJson implements ArrayAccess, Countable, IteratorAggregate
{
private $__resp;
- public function __construct($response)
+ private $__auth = EpiTwitter::EPITWITTER_AUTH_OAUTH;
+ public function __construct($response, $auth = null)
{
$this->__resp = $response;
+ if($auth !== null)
+ $this->__auth = $auth;
}
// Implementation of the IteratorAggregate::getIterator() to support foreach ($this as $...)
@@ -97,9 +117,20 @@ public function offsetGet($offset)
public function __get($name)
{
if($this->__resp->code != 200 && $name !== 'responseText')
- EpiOAuthException::raise($this->__resp->data, $this->__resp->code);
+ {
+ switch($this->__auth)
+ {
+ case EpiTwitter::EPITWITTER_AUTH_OAUTH:
+ EpiOAuthException::raise($this->__resp->data, $this->__resp->code);
+ case EpiTwitter::EPITWITTER_AUTH_BASIC:
+ throw new EpiTwitterException($this->__resp->data, $this->__resp->code);
+ default:
+ throw new Exception("Unknown EpiTwitter Exception. Response: {$this->__resp->data}", $this->__resp->code);
+ }
+ }
$this->responseText = $this->__resp->data;
+ $this->code = $this->__resp->code;
$this->response = json_decode($this->responseText, 1);
$this->__obj = json_decode($this->responseText);
@@ -120,3 +151,5 @@ public function __isset($name)
return empty($name);
}
}
+
+class EpiTwitterException extends Exception {}
View
14 tests/EpiTwitterTest.php
@@ -14,6 +14,7 @@ function setUp()
$token = '25451974-uakRmTZxrSFQbkDjZnTAsxDO5o9kacz2LT6kqEHA';
$secret= 'CuQPQ1WqIdSJDTIkDUlXjHpbcRao9lcKhQHflqGE8';
$this->twitterObj = new EpiTwitter($consumer_key, $consumer_secret, $token, $secret);
+ $this->twitterObjBasic = new EpiTwitter();
$this->screenName = 'jmathai_test';
}
@@ -57,7 +58,7 @@ function testPostStatus()
$this->assertEquals($resp->text, $statusText, 'The status was not updated correctly');
// reply to it
$statusText = 'Testing a random status with reply to id (reply to: ' . $resp->id . ')';
- $resp = $this->twitterObj->post_statusesUpdate(array('status' => $statusText, 'in_reply_to_status_id' => $resp->id));
+ $resp = $this->twitterObj->post_statusesUpdate(array('status' => $statusText, 'in_reply_to_status_id' => "{$resp->id}"));
$this->assertEquals($resp->text, $statusText, 'The status with reply to id was not updated correctly');
}
@@ -106,14 +107,14 @@ function testResponseAccess()
function testSearch()
{
- $resp = $this->twitterObj->get_search(array('q' => 'hello'));
+ $resp = $this->twitterObjBasic->get_search(array('q' => 'hello'));
$this->assertTrue(is_array($resp->response['results']));
$this->assertTrue(!empty($resp->results[0]->text), "search response is not an array {$resp->results[0]->text}");
}
function testTrends()
{
- $resp = $this->twitterObj->get_trends();
+ $resp = $this->twitterObjBasic->get_trends();
$this->assertTrue(is_array($resp->response['trends']), "trends is empty");
$this->assertTrue(!empty($resp->trends[0]->name), "current trends is not an array " . $resp->trends[0]->name);
@@ -140,4 +141,11 @@ function testCount()
$resp = $this->twitterObj->$method(array('page' => 100));
$this->assertTrue(count($resp) == 0, "Page 100 should return a count of 0");
}
+ function testUpdateAvatar()
+ {
+ $file = dirname(__FILE__) . '/avatar_test_image.jpg';
+ $resp = $this->twitterObj->post_accountUpdate_profile_image(array('@image' => "@{$file}"));
+ // api seems to be a bit behind and doesn't respond with the new image url - use code instead for now
+ $this->assertEquals($resp->code, 200, 'Response code was not 200');
+ }
}
View
BIN  tests/avatar_test_image.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Please sign in to comment.
Something went wrong with that request. Please try again.