From 4f69c2e531f50ab7c40997a30458b2d9d14a8bd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?I=C3=B1aki=20Abete?= Date: Mon, 24 Jun 2013 15:20:39 -0300 Subject: [PATCH 01/29] composer.json updated for Packagist submission --- composer.json | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 1cee76c..7cb32fd 100644 --- a/composer.json +++ b/composer.json @@ -1,12 +1,25 @@ { - "name": "jobiwankanobi/stackmobphp", + "name": "jobiwankanobi/stackmob", + "description": "Simple PHP API for Stackmob based on sparse project from spacious/sparse", + "license": "MIT", + "authors": [ + { + "name": "James OBrien" + } + ], + "require": { "php": ">=5.4.0", - "apache/log4php": "2.3.0" + "apache/log4php": "2.3.0" }, "require-dev": { - "phpunit/phpunit": "3.7.5", + "phpunit/phpunit": "3.7.5", "phpunit/php-invoker": ">=1.1.0", - "phpunit/php-code-coverage": "1.2.6" + "phpunit/php-code-coverage": "1.2.6" + }, + "autoload": { + "psr-0": { + "Stackmob": "src/" + } } } From 1a983010da10bc6e5d9c0692c439ba40c437fef9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?I=C3=B1aki=20Abete?= Date: Mon, 24 Jun 2013 16:02:44 -0300 Subject: [PATCH 02/29] Updated for packagist submission --- composer.json | 2 +- src/Stackmob/CustomCode.php | 2 ++ src/Stackmob/OAuth2Signer.php | 1 - src/Stackmob/Rest.php | 8 +++++--- src/Stackmob/Stackmob.php | 17 +---------------- src/Stackmob/User.php | 1 - 6 files changed, 9 insertions(+), 22 deletions(-) diff --git a/composer.json b/composer.json index 7cb32fd..5e2cb1a 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ }, "autoload": { "psr-0": { - "Stackmob": "src/" + "Stackmob": "src/Stackmob/" } } } diff --git a/src/Stackmob/CustomCode.php b/src/Stackmob/CustomCode.php index 5de452f..ebc02eb 100644 --- a/src/Stackmob/CustomCode.php +++ b/src/Stackmob/CustomCode.php @@ -5,6 +5,8 @@ namespace Stackmob; +use Stackmob\Stackmob; + class CustomCode extends Stackmob { const API_PATH = 'http://api.mob1.stackmob.com/'; diff --git a/src/Stackmob/OAuth2Signer.php b/src/Stackmob/OAuth2Signer.php index 4209fee..65dc58d 100644 --- a/src/Stackmob/OAuth2Signer.php +++ b/src/Stackmob/OAuth2Signer.php @@ -1,7 +1,6 @@ Date: Mon, 24 Jun 2013 17:11:01 -0300 Subject: [PATCH 03/29] Mmmm --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 5e2cb1a..1d55cff 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "jobiwankanobi/stackmob", + "name": "inakiabt/stackmob", "description": "Simple PHP API for Stackmob based on sparse project from spacious/sparse", "license": "MIT", "authors": [ From f93bda5573565ed9d1a29f065af43eded1a85430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?I=C3=B1aki=20Abete?= Date: Mon, 24 Jun 2013 17:14:05 -0300 Subject: [PATCH 04/29] Added require all default config --- composer.json | 6 +++--- src/Stackmob/require.php | 11 +++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 src/Stackmob/require.php diff --git a/composer.json b/composer.json index 1d55cff..984c456 100644 --- a/composer.json +++ b/composer.json @@ -18,8 +18,8 @@ "phpunit/php-code-coverage": "1.2.6" }, "autoload": { - "psr-0": { - "Stackmob": "src/Stackmob/" - } + "files": [ + "src/Stackmob/require.php" + ] } } diff --git a/src/Stackmob/require.php b/src/Stackmob/require.php new file mode 100644 index 0000000..0dbe245 --- /dev/null +++ b/src/Stackmob/require.php @@ -0,0 +1,11 @@ + Date: Mon, 24 Jun 2013 17:15:22 -0300 Subject: [PATCH 05/29] Rollback customcode import --- src/Stackmob/CustomCode.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Stackmob/CustomCode.php b/src/Stackmob/CustomCode.php index ebc02eb..5de452f 100644 --- a/src/Stackmob/CustomCode.php +++ b/src/Stackmob/CustomCode.php @@ -5,8 +5,6 @@ namespace Stackmob; -use Stackmob\Stackmob; - class CustomCode extends Stackmob { const API_PATH = 'http://api.mob1.stackmob.com/'; From 7ec0982c90774db2876bd230b092047648af748f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?I=C3=B1aki=20Abete?= Date: Mon, 24 Jun 2013 17:16:55 -0300 Subject: [PATCH 06/29] Missing Stackmob require --- src/Stackmob/Stackmob.php | 3 +-- src/Stackmob/require.php | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Stackmob/Stackmob.php b/src/Stackmob/Stackmob.php index cef69f0..2228a37 100644 --- a/src/Stackmob/Stackmob.php +++ b/src/Stackmob/Stackmob.php @@ -7,5 +7,4 @@ class Stackmob { * @var Rest */ protected static $_restClient; -} -\Logger::configure(__DIR__ . '/log4php.xml'); \ No newline at end of file +} \ No newline at end of file diff --git a/src/Stackmob/require.php b/src/Stackmob/require.php index 0dbe245..bfbb0e8 100644 --- a/src/Stackmob/require.php +++ b/src/Stackmob/require.php @@ -1,6 +1,7 @@ Date: Sat, 6 Jul 2013 05:18:55 -0300 Subject: [PATCH 07/29] Better erro handling --- src/Stackmob/Rest.php | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/src/Stackmob/Rest.php b/src/Stackmob/Rest.php index 5abeb04..36b55ae 100644 --- a/src/Stackmob/Rest.php +++ b/src/Stackmob/Rest.php @@ -522,15 +522,35 @@ function isLoginSessionExpired() { else return false; } + + function processPostData($postData) + { + if (is_array($postData)) + { + foreach ($postData as $key => $value) + { + if (is_array($value) && isset($value['binary'])) + { + $content_type = empty($value['content-type']) ? 'text/html' : $value['content-type']; + $filename = empty($value['filename']) ? 'file.html' : $value['filename']; + $postData[$key] = "Content-Type: {$content_type}\nContent-Disposition: attachment; filename={$filename}\nContent-Transfer-Encoding: base64\n\n".base64_encode($value['binary']); + } + } + } + + return $postData; + } function send_request($http_method, $url, $auth_header=null, $postData=null, $headers=null) { $version = Rest::$DEVELOPMENT ? 0 : 1; $curl = curl_init($url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); - curl_setopt($curl, CURLOPT_FAILONERROR, true); + // curl_setopt($curl, CURLOPT_FAILONERROR, true); // Don't verify peer in developer mode curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, !Rest::$DEVELOPMENT); - curl_setopt($curl, CURLOPT_HEADER, true); + curl_setopt($curl, CURLOPT_HEADER, false); + + $postData = $this->processPostData($postData); switch($http_method) { case 'GET': @@ -578,17 +598,18 @@ function send_request($http_method, $url, $auth_header=null, $postData=null, $he break; } - $this->log->debug( $curl."\n\n"); - $response = curl_exec($curl); - $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); + $err = curl_errno ( $curl ); + $errmsg = curl_error ( $curl ); + $header = curl_getinfo ( $curl ); + $statusCode = curl_getinfo ( $curl, CURLINFO_HTTP_CODE ); + curl_close($curl); + $this->log->debug("Response: $response"); $this->log->debug("Status code: $statusCode"); - if (!$response && $statusCode !== 200) { - $response = curl_error($curl); - curl_close($curl); - - throw new StackmobException($response, $statusCode); + if ($statusCode >= 400 && $statusCode !== 0) { + $this->log->debug("Errorno: $err"); + throw new StackmobException($response, $statusCode); } else { list($header, $body) = explode("\r\n\r\n", $response, 2); @@ -605,8 +626,6 @@ function send_request($http_method, $url, $auth_header=null, $postData=null, $he if(is_object($decoded) || is_array($decoded) ){ $this->_results = $decoded; } - curl_close($curl); - return $this->_results; } } From 1b165fab63c4a5dd8d815790d70e1506949c5d8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?I=C3=B1aki=20Abete?= Date: Wed, 10 Jul 2013 02:03:25 -0300 Subject: [PATCH 08/29] Bugfix: request result object is empty --- src/Stackmob/Rest.php | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/Stackmob/Rest.php b/src/Stackmob/Rest.php index 36b55ae..fa30629 100644 --- a/src/Stackmob/Rest.php +++ b/src/Stackmob/Rest.php @@ -611,17 +611,11 @@ function send_request($http_method, $url, $auth_header=null, $postData=null, $he $this->log->debug("Errorno: $err"); throw new StackmobException($response, $statusCode); } else { - - list($header, $body) = explode("\r\n\r\n", $response, 2); - $this->log->debug("Header: $header"); - $this->log->debug("Body: $body"); - $this->_responseHeaders = $this->http_parse_headers($header); - $this->_statusCode = $statusCode; - $this->_response = $body; + $this->_response = $response; $this->_results = null; - $decoded = json_decode($body); + $decoded = json_decode($response); if(is_object($decoded) || is_array($decoded) ){ $this->_results = $decoded; From 8065cc086fd88c011fbc4964995127977ca94067 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?I=C3=B1aki=20Abete?= Date: Thu, 11 Jul 2013 15:56:05 -0300 Subject: [PATCH 09/29] Removed default StackMob log4php configuration --- src/Stackmob/require.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stackmob/require.php b/src/Stackmob/require.php index bfbb0e8..8ad40ad 100644 --- a/src/Stackmob/require.php +++ b/src/Stackmob/require.php @@ -1,5 +1,5 @@ Date: Tue, 6 Aug 2013 03:06:41 -0500 Subject: [PATCH 10/29] Add push notifications --- src/Stackmob/Push.php | 36 ++++++++++++++---------------------- src/Stackmob/Rest.php | 23 +++++++++++++++++++---- src/Stackmob/require.php | 1 + 3 files changed, 34 insertions(+), 26 deletions(-) diff --git a/src/Stackmob/Push.php b/src/Stackmob/Push.php index c90806b..810aa31 100644 --- a/src/Stackmob/Push.php +++ b/src/Stackmob/Push.php @@ -2,7 +2,7 @@ /** * Push */ -namespace Sparse; +namespace Stackmob; class Push { @@ -13,32 +13,24 @@ class Push { /** * @param $data - The data of the push notification. Valid fields are: - * channels - An Array of channels to push to. - * push_time - A Date object for when to send the push. - * expiration_time - A Date object for when to expire the push. - * expiration_interval - The seconds from now to expire the push. - * where - A Parse.Query over Parse.Installation that is used to match a set of installations to push to. - * data - The data to send as part of the push + * - alert : the message to display + * - badge : an iOS-specific value that changes the badge of the application icon (number or "Increment") + * - sound : an iOS-specific string representing the name of a sound file in the application bundle to play. * @return array|null */ - public static function send($data){ + public static function send($data, $users = array()){ if(!Push::$_restClient){ - Push::$_restClient = new \Sparse\Rest(); + Push::$_restClient = new \Stackmob\Rest(); } - // Rest API is a little easier - if(!empty($data['channels']) && !empty($data['data'])){ - - $params = $data; - $data = $params['data']; - unset($params['data']); - $channels = $params['channels']; - unset($params['channels']); - - return Push::$_restClient->push($channels,$data,$params); - } - - return null; + return Push::$_restClient->push($data, $users); } + + /** + * Initialize is an empty function by default. Override it with your own initialization logic. + */ + public function initialize(){ + // empty + } } diff --git a/src/Stackmob/Rest.php b/src/Stackmob/Rest.php index fa30629..c8d703b 100644 --- a/src/Stackmob/Rest.php +++ b/src/Stackmob/Rest.php @@ -187,12 +187,16 @@ public function deleteObject($objectClass,$pk,$objectId){ * * @return array */ - public function push($channels,$data,$params=array()){ + public function push($payload,$users=array()){ - $path = Rest::PUSH_PATH; + $this->_apiUrl = Rest::PUSH_PATH; + $path = 'notifications'; - $params['channels'] = $channels; - $params['data'] = $data; + $params['payload'] = $payload; + if (!empty($users)) + { + $params['users'] = $users; + } return $this->post($path,$params); } @@ -550,6 +554,17 @@ function send_request($http_method, $url, $auth_header=null, $postData=null, $he curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, !Rest::$DEVELOPMENT); curl_setopt($curl, CURLOPT_HEADER, false); + if (is_array($postData)) + { + $this->log->debug("Request Body: ".json_encode(array_map(function($value){ + if (is_array($value) && isset($value['binary'])) + { + return '[binary]'; + } + return $value; + }, $postData))); + } + $postData = $this->processPostData($postData); switch($http_method) { diff --git a/src/Stackmob/require.php b/src/Stackmob/require.php index 8ad40ad..05d3607 100644 --- a/src/Stackmob/require.php +++ b/src/Stackmob/require.php @@ -5,6 +5,7 @@ include("OAuth.php"); include("Rest.php"); include("Object.php"); +include("Push.php"); include("User.php"); include("Query.php"); include("CustomCode.php"); From 4a306744bfe80351d6d6c3841e38551335425f51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?I=C3=B1aki=20Abete?= Date: Thu, 8 Aug 2013 17:09:03 -0300 Subject: [PATCH 11/29] Update composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 984c456..19ff32a 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ ], "require": { - "php": ">=5.4.0", + "php": ">=5.3.0", "apache/log4php": "2.3.0" }, "require-dev": { From f470b479e35858197644b79368b83462b9ffb606 Mon Sep 17 00:00:00 2001 From: Federico Freire Date: Mon, 19 Aug 2013 21:50:08 -0500 Subject: [PATCH 12/29] Composer updated --- composer.json | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/composer.json b/composer.json index 19ff32a..4d86748 100644 --- a/composer.json +++ b/composer.json @@ -1,13 +1,17 @@ { - "name": "inakiabt/stackmob", - "description": "Simple PHP API for Stackmob based on sparse project from spacious/sparse", + "name": "productgram/stackmobphp", + "description": "Simple PHP API for Stackmob based on inakiabt/stackmob project", "license": "MIT", "authors": [ - { - "name": "James OBrien" - } + { + "name": "IƱaki Abete", + "email": "inakiabt@gmail.com" + }, + { + "name": "Federico Freire", + "email": "nerdscape@gmail.com" + } ], - "require": { "php": ">=5.3.0", "apache/log4php": "2.3.0" @@ -18,8 +22,6 @@ "phpunit/php-code-coverage": "1.2.6" }, "autoload": { - "files": [ - "src/Stackmob/require.php" - ] + "psr-0": { "": "src/" } } } From c2d005db032451e7bc6e727e4404261c0cb1b014 Mon Sep 17 00:00:00 2001 From: Federico Freire Date: Wed, 21 Aug 2013 13:05:10 -0500 Subject: [PATCH 13/29] Apache Log4PHP removed. --- composer.json | 3 +- src/Stackmob/DummyLogger.php | 15 ++++ src/Stackmob/Object.php | 17 ++++- src/Stackmob/Query.php | 2 +- src/Stackmob/Rest.php | 126 +++++----------------------------- src/Stackmob/log4php.xml | 15 ---- src/Stackmob/require.php | 1 - tests/Stackmob/ObjectTest.php | 1 - tests/Stackmob/QueryTest.php | 2 +- tests/Stackmob/UserTest.php | 2 +- 10 files changed, 51 insertions(+), 133 deletions(-) create mode 100644 src/Stackmob/DummyLogger.php delete mode 100644 src/Stackmob/log4php.xml diff --git a/composer.json b/composer.json index 4d86748..5a20ce3 100644 --- a/composer.json +++ b/composer.json @@ -13,8 +13,7 @@ } ], "require": { - "php": ">=5.3.0", - "apache/log4php": "2.3.0" + "php": ">=5.3.0" }, "require-dev": { "phpunit/phpunit": "3.7.5", diff --git a/src/Stackmob/DummyLogger.php b/src/Stackmob/DummyLogger.php new file mode 100644 index 0000000..3eaa8d9 --- /dev/null +++ b/src/Stackmob/DummyLogger.php @@ -0,0 +1,15 @@ +save(); } } - protected function setUpLog() { - $this->log = \Logger::getLogger(__CLASS__); + + /** + * Public, so its inherited. + */ + public function setUpLog($logger) + { + if (empty($logger)) { + return; + } + + $this->log = $logger; } /** @@ -54,7 +63,9 @@ protected function setUpLog() { * @param $pk */ public function __construct($objectClass,$attributes=array(), $pk=null){ - $this->setUpLog(); + + // just to make sure the logging does not fails if used before setUpLog + $this->log = new DummyLogger(); $this->objectClass = $objectClass; $this->_pk = $pk ? $pk : strtolower($objectClass) . '_id'; diff --git a/src/Stackmob/Query.php b/src/Stackmob/Query.php index a74f4a0..204efb5 100644 --- a/src/Stackmob/Query.php +++ b/src/Stackmob/Query.php @@ -25,7 +25,7 @@ class Query extends Object { * @param type $pk */ public function __construct($objectClass, $pk = null){ - $this->log = \Logger::getLogger(__CLASS__); + $this->log = new DummyLogger(); $this->objectClass = $objectClass; $this->_pk = $pk ? $pk : strtolower($objectClass) . '_id'; diff --git a/src/Stackmob/Rest.php b/src/Stackmob/Rest.php index c8d703b..fc4ff22 100644 --- a/src/Stackmob/Rest.php +++ b/src/Stackmob/Rest.php @@ -44,15 +44,25 @@ class Rest { protected $log; public function __construct($apiUrl = null) { - $this->_apiUrl = $apiUrl ? $apiUrl : Rest::API_URL; - $this->_isSecure = Rest::startsWith($this->_apiUrl, "https"); - $this->_oauthConsumer = new OAuthConsumer(Rest::$consumerKey, Rest::$consumerSecret, NULL); - $this->log = \Logger::getLogger(__CLASS__); - $this->log->debug("Is Secure: " . $this->_isSecure); - $this->log->debug("apiUrl: " . $this->_apiUrl); + $this->_apiUrl = $apiUrl ? $apiUrl : Rest::API_URL; + $this->_isSecure = Rest::startsWith($this->_apiUrl, "https"); + $this->_oauthConsumer = new OAuthConsumer(Rest::$consumerKey, Rest::$consumerSecret, NULL); + + // just to make sure the logging does not fails if used before setUpLog + $this->log = new DummyLogger(); } - - + + public function setUpLog($logger) + { + if (empty($logger)) { + return; + } + + $this->log = $logger; + $this->log->debug(__CLASS__ . " - Is Secure: " . $this->_isSecure); + $this->log->debug(__CLASS__ . " - apiUrl: " . $this->_apiUrl); + } + public static function startsWith($haystack, $needle) { $length = strlen($needle); @@ -759,103 +769,3 @@ protected function http_parse_headers($header) { } } - - -// $this->log->debug("Request url: $url"); -// if($http_method === 'GET' || $http_method === 'DELETE') -// $contentLength = 0; -// else -// $contentLength = strlen(json_encode($postData)); -// $rest = new \RestClient(array( -// 'user_agent' => 'stackmobphp 0.1', -// 'headers' => array( -// 'Content-Type' => 'application/vnd.stackmob+json', -// 'Content-Length' => $contentLength, -// 'Accept' => "application/vnd.stackmob+json; version=$version", -// 'X-StackMob-API-Key' => Rest::$consumerKey, -// 'X-StackMob-User-Agent' => 'stackmobphp 0.1' -// ), -// 'curl_options' => array ( -// CURLOPT_SSL_VERIFYPEER => !Rest::$DEVELOPMENT, -// CURLOPT_RETURNTRANSFER => true, -// CURLOPT_FAILONERROR => true -// ), -// 'format' => "json")); -// switch($http_method) { -// case 'GET': -// $result = $rest->get($url,null,$headers); -// break; -// case 'POST': -// $result = $rest->post($url,$postData,$headers); -// break; -// case 'PUT': -// $result = $rest->put($url,$postData,$headers); -// break; -// case 'DELETE': -// $result = $rest->delete($url,null,$headers); -// break; -// } -// $statusCode = $result->info->http_code; -// $error = $result->error; -// if(!$result->response && $statusCode != 200) { -// throw new StackmobException($error, $statusCode); -// } -// $decoded = json_decode($result->response); -// if(is_object($decoded)){ -// $this->_results = $decoded; -// } -// return $this->_results; - - -// /** -// * @param $path -// * @param array $postData -// * @param null $headers -// * @return mixed -// * @throws StackmobException -// */ -// protected function loginRequest($path,$postData=array(),$headers=null) { -// $postData['token_type'] = 'mac'; -//// $endpoint = $this->_apiUrl.'/'.$path; -// $version = Rest::$DEVELOPMENT ? 0 : 1; -// -// $rest = new \RestClient(array( -// 'base_url' => $this->_apiUrl, -// 'user_agent' => 'stackmobphp 0.1', -// 'headers' => array( -// 'Content-Type' => 'application/x-www-form-urlencoded', -// 'Content-Length' => strlen(http_build_query($postData)), -// 'Accept' => "application/vnd.stackmob+json; version=$version", -// 'X-StackMob-API-Key' => Rest::$consumerKey, -// 'X-StackMob-User-Agent' => 'stackmobphp 0.1' -// ), -// 'curl_options' => array ( -// CURLOPT_SSL_VERIFYPEER => !Rest::$DEVELOPMENT, -// CURLOPT_RETURNTRANSFER => true, -// CURLOPT_FAILONERROR => true -// ), -// 'format' => "")); -// $result = $rest->post($path, $postData, $headers); -// $statusCode = $result->info->http_code; -// $error = $result->error; -// if(!$result->response && $statusCode != 200) { -// throw new StackmobException($error, $statusCode); -// } -// $decoded = json_decode($result->response); -// -// if(is_object($decoded)){ -// $this->log->debug(print_r($decoded, true)); -// session_start(); -// $_SESSION[Rest::SM_LOGIN_ACCESS_TOKEN] = $decoded->access_token; -// if(isset($decoded->mac_key)) -// $_SESSION[Rest::SM_LOGIN_MAC_KEY] = $decoded->mac_key; -// $_SESSION[Rest::SM_LOGIN_TOKEN_EXPIRES] = time() + $decoded->expires_in; -// $_SESSION[Rest::SM_LOGIN_REFRESH_TOKEN] = $decoded->refresh_token; -// $_SESSION[User::SM_LOGGED_IN_USER] = json_encode($decoded->stackmob->user); -// $_SESSION[User::SM_LOGGED_IN_USERNAME] = $decoded->stackmob->user->username; -// } else { -// throw new StackmobException("Unable to decode json response: " . $result->response); -// } -// -// return $decoded->stackmob->user; -// } diff --git a/src/Stackmob/log4php.xml b/src/Stackmob/log4php.xml deleted file mode 100644 index 47fae93..0000000 --- a/src/Stackmob/log4php.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/src/Stackmob/require.php b/src/Stackmob/require.php index 05d3607..baa0a01 100644 --- a/src/Stackmob/require.php +++ b/src/Stackmob/require.php @@ -1,5 +1,4 @@ log = \Logger::getLogger(__CLASS__); // Set up test objects $this->objects = array(); diff --git a/tests/Stackmob/QueryTest.php b/tests/Stackmob/QueryTest.php index 9b0fcd7..cdb87d6 100644 --- a/tests/Stackmob/QueryTest.php +++ b/tests/Stackmob/QueryTest.php @@ -18,7 +18,7 @@ public function setUp() { parent::setUp(); Rest::$consumerKey = "a368126f-4b41-4e54-ac45-394df81fe404"; Rest::$consumerSecret = "1dd779df-ab0e-446b-8bdb-52641ef97df4"; - $this->log = \Logger::getLogger(__CLASS__); + $this->log = new DummyLogger(); $user = new User(array("username" => "jimbo", "password" => "123456", "age" => 25)); $user->signUp(); diff --git a/tests/Stackmob/UserTest.php b/tests/Stackmob/UserTest.php index baf922d..e7914c7 100644 --- a/tests/Stackmob/UserTest.php +++ b/tests/Stackmob/UserTest.php @@ -19,7 +19,7 @@ public function setUp() { parent::setUp(); Rest::$consumerKey = "a368126f-4b41-4e54-ac45-394df81fe404"; Rest::$consumerSecret = "1dd779df-ab0e-446b-8bdb-52641ef97df4"; - $this->log = \Logger::getLogger(__CLASS__); + $this->log = new DummyLogger(); $this->log->debug("TEST: PHPVERSION" . PHP_VERSION); } From 7372cdfa3630857f62ec6edc3b02d3b0ec7a6c0d Mon Sep 17 00:00:00 2001 From: Federico Freire Date: Wed, 21 Aug 2013 14:26:38 -0500 Subject: [PATCH 14/29] OAuth library changed. --- composer.json | 9 +- src/Stackmob/OAuth.php | 897 ---------------------------------- src/Stackmob/OAuth2Signer.php | 4 +- src/Stackmob/Rest.php | 3 + src/Stackmob/require.php | 1 - 5 files changed, 14 insertions(+), 900 deletions(-) delete mode 100644 src/Stackmob/OAuth.php diff --git a/composer.json b/composer.json index 5a20ce3..e493cb2 100644 --- a/composer.json +++ b/composer.json @@ -12,8 +12,15 @@ "email": "nerdscape@gmail.com" } ], + "repositories": [ + { + "type": "vcs", + "url": "git@bitbucket.org:productgram/pgf_oauth.git" + } + ], "require": { - "php": ">=5.3.0" + "php": ">=5.3.0", + "productgram/pgf_oauth": "dev-master" }, "require-dev": { "phpunit/phpunit": "3.7.5", diff --git a/src/Stackmob/OAuth.php b/src/Stackmob/OAuth.php deleted file mode 100644 index d18b078..0000000 --- a/src/Stackmob/OAuth.php +++ /dev/null @@ -1,897 +0,0 @@ -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=" . - \Stackmob\OAuthUtil::urlencode_rfc3986($this->key) . - "&oauth_token_secret=" . - \Stackmob\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); - - // Check for zero length, although unlikely here - if (strlen($built) == 0 || strlen($signature) == 0) { - return false; - } - - if (strlen($built) != strlen($signature)) { - return false; - } - - // Avoid a timing leak with a (hopefully) time insensitive compare - $result = 0; - for ($i = 0; $i < strlen($signature); $i++) { - $result |= ord($built{$i}) ^ ord($signature{$i}); - } - - return $result == 0; - } -} - -/** - * 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 = \Stackmob\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 = \Stackmob\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 { - protected $parameters; - protected $http_method; - protected $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 = ($parameters) ? $parameters : array(); - $parameters = array_merge( \Stackmob\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 = ($http_url) ? $http_url : $scheme . - '://' . $_SERVER['SERVER_NAME'] . - ':' . - $_SERVER['SERVER_PORT'] . - $_SERVER['REQUEST_URI']; - $http_method = ($http_method) ? $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 = \Stackmob\OAuthUtil::get_headers(); - - // Parse the query-string to find GET parameters - $parameters = \Stackmob\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" - && isset($request_headers['Content-Type']) - && strstr($request_headers['Content-Type'], - 'application/x-www-form-urlencoded') - ) { - $post_data = \Stackmob\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 (isset($request_headers['Authorization']) && substr($request_headers['Authorization'], 0, 6) == 'OAuth ') { - $header_parameters = \Stackmob\OAuthUtil::split_header( - $request_headers['Authorization'] - ); - $parameters = array_merge($parameters, $header_parameters); - } - - } - - return new \Stackmob\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 = ($parameters) ? $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 \Stackmob\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 \Stackmob\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 = \Stackmob\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); - - $scheme = (isset($parts['scheme'])) ? $parts['scheme'] : 'http'; - $port = (isset($parts['port'])) ? $parts['port'] : (($scheme == 'https') ? '443' : '80'); - $host = (isset($parts['host'])) ? strtolower($parts['host']) : ''; - $path = (isset($parts['path'])) ? $parts['path'] : ''; - - 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 \Stackmob\OAuthUtil::build_http_query($this->parameters); - } - - /** - * builds the Authorization: header - */ - public function to_header($realm=null) { - $first = true; - if($realm) { - $out = 'Authorization: OAuth realm="' . \Stackmob\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 \Stackmob\OAuthException('Arrays not supported in headers'); - } - $out .= ($first) ? ' ' : ','; - $out .= \Stackmob\OAuthUtil::urlencode_rfc3986($k) . - '="' . - \Stackmob\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 - */ - public static function generate_timestamp() { - return time(); - } - - /** - * util function: current nonce - */ - public 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 \Stackmob\OAuthException("OAuth version '$version' not supported"); - } - return $version; - } - - /** - * figure out the signature with some defaults - */ - private function get_signature_method($request) { - $signature_method = $request instanceof \Stackmob\OAuthRequest - ? $request->get_parameter("oauth_signature_method") - : NULL; - - 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 \Stackmob\OAuthException('No signature method parameter. This parameter is required'); - } - - if (!in_array($signature_method, - array_keys($this->signature_methods))) { - throw new \Stackmob\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 instanceof OAuthRequest - ? $request->get_parameter("oauth_consumer_key") - : NULL; - - if (!$consumer_key) { - throw new \Stackmob\OAuthException("Invalid consumer key"); - } - - $consumer = $this->data_store->lookup_consumer($consumer_key); - if (!$consumer) { - throw new \Stackmob\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 instanceof \Stackmob\OAuthRequest - ? $request->get_parameter('oauth_token') - : NULL; - - $token = $this->data_store->lookup_token( - $consumer, $token_type, $token_field - ); - if (!$token) { - throw new \Stackmob\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 instanceof \Stackmob\OAuthRequest - ? $request->get_parameter('oauth_timestamp') - : NULL; - $nonce = $request instanceof \Stackmob\OAuthRequest - ? $request->get_parameter('oauth_nonce') - : NULL; - - $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 \Stackmob\OAuthException("Invalid signature"); - } - } - - /** - * check that the timestamp is new enough - */ - private function check_timestamp($timestamp) { - if( ! $timestamp ) - throw new \Stackmob\OAuthException( - 'Missing timestamp parameter. The parameter is required' - ); - - // verify that timestamp is recentish - $now = time(); - if (abs($now - $timestamp) > $this->timestamp_threshold) { - throw new \Stackmob\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 \Stackmob\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 \Stackmob\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('\Stackmob\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) - // May 28th, 2010 - method updated to tjerk.meesters for a speed improvement. - // see http://code.google.com/p/oauth/issues/detail?id=163 - public static function split_header($header, $only_allow_oauth_parameters = true) { - $params = array(); - if (preg_match_all('/('.($only_allow_oauth_parameters ? 'oauth_' : '').'[a-z_-]*)=(:?"([^"]*)"|([^,]*))/', $header, $matches)) { - foreach ($matches[1] as $i => $h) { - $params[$h] = \Stackmob\OAuthUtil::urldecode_rfc3986(empty($matches[3][$i]) ? $matches[4][$i] : $matches[3][$i]); - } - 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]) ? \Stackmob\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 = \Stackmob\OAuthUtil::urlencode_rfc3986(array_keys($params)); - $values = \Stackmob\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) - // June 12th, 2010 - changed to sort because of issue 164 by hidetaka - sort($value, SORT_STRING); - 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); - } -} - -?> \ No newline at end of file diff --git a/src/Stackmob/OAuth2Signer.php b/src/Stackmob/OAuth2Signer.php index 65dc58d..320d30e 100644 --- a/src/Stackmob/OAuth2Signer.php +++ b/src/Stackmob/OAuth2Signer.php @@ -1,6 +1,8 @@ 1 ? $splitHost[0] : $hostWithPort; $port = count($splitHost) > 1 ? $splitHost[1] : 80; //use default port 80 if http. If you're using https then this should be 443 - $ts = \Stackmob\OAuthRequest::generate_timestamp(); + $ts = OAuthRequest::generate_timestamp(); $nonce = substr(number_format(hexdec(sha1(microtime(true).mt_rand(10000,90000))),0,'',''), 0, 17); $base = $this->_createBaseString($ts, $nonce, $method, $path, $hostNoPort, $port); diff --git a/src/Stackmob/Rest.php b/src/Stackmob/Rest.php index fc4ff22..5e44913 100644 --- a/src/Stackmob/Rest.php +++ b/src/Stackmob/Rest.php @@ -10,6 +10,9 @@ use Stackmob\StackmobException; use Stackmob\LoginSessionExpiredException; +use ProductGram\Security\OAuth\OAuthConsumer; +use ProductGram\Security\OAuth\OAuthSignatureMethodHMACSHA1; + class Rest { public static $consumerKey; diff --git a/src/Stackmob/require.php b/src/Stackmob/require.php index baa0a01..faeca5b 100644 --- a/src/Stackmob/require.php +++ b/src/Stackmob/require.php @@ -1,7 +1,6 @@ Date: Wed, 21 Aug 2013 15:05:07 -0500 Subject: [PATCH 15/29] Fixed OAuth namespace usage. --- src/Stackmob/OAuth2Signer.php | 4 ++-- src/Stackmob/Rest.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Stackmob/OAuth2Signer.php b/src/Stackmob/OAuth2Signer.php index 320d30e..9eb3a72 100644 --- a/src/Stackmob/OAuth2Signer.php +++ b/src/Stackmob/OAuth2Signer.php @@ -1,7 +1,6 @@ _accessToken = $accessToken; $this->_macKey = $macKey; + } // Private Methods @@ -91,7 +91,7 @@ function generateMAC($method, $fullHost, $path) { $splitHost = preg_split('/:/', $hostWithPort); $hostNoPort = count($splitHost) > 1 ? $splitHost[0] : $hostWithPort; $port = count($splitHost) > 1 ? $splitHost[1] : 80; //use default port 80 if http. If you're using https then this should be 443 - $ts = OAuthRequest::generate_timestamp(); + $ts = time(); $nonce = substr(number_format(hexdec(sha1(microtime(true).mt_rand(10000,90000))),0,'',''), 0, 17); $base = $this->_createBaseString($ts, $nonce, $method, $path, $hostNoPort, $port); diff --git a/src/Stackmob/Rest.php b/src/Stackmob/Rest.php index 5e44913..74306a1 100644 --- a/src/Stackmob/Rest.php +++ b/src/Stackmob/Rest.php @@ -10,8 +10,8 @@ use Stackmob\StackmobException; use Stackmob\LoginSessionExpiredException; -use ProductGram\Security\OAuth\OAuthConsumer; -use ProductGram\Security\OAuth\OAuthSignatureMethodHMACSHA1; +use OAuth\OAuthConsumer; +use OAuth\OAuthSignatureMethodHMACSHA1; class Rest { From d98934e3295a283bd660b01715f61ce6b7ada607 Mon Sep 17 00:00:00 2001 From: Federico Freire Date: Wed, 21 Aug 2013 15:55:48 -0500 Subject: [PATCH 16/29] Namespace fixed in composer. Namespace conflict fixed in Rest.php --- composer.json | 2 +- src/Stackmob/Rest.php | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/composer.json b/composer.json index e493cb2..4119603 100644 --- a/composer.json +++ b/composer.json @@ -28,6 +28,6 @@ "phpunit/php-code-coverage": "1.2.6" }, "autoload": { - "psr-0": { "": "src/" } + "psr-0": { "Stackmob": "src/" } } } diff --git a/src/Stackmob/Rest.php b/src/Stackmob/Rest.php index 74306a1..59b3853 100644 --- a/src/Stackmob/Rest.php +++ b/src/Stackmob/Rest.php @@ -5,7 +5,6 @@ */ namespace Stackmob; -use Stackmob\OAuthConsumer; use Stackmob\OAuth2Signer; use Stackmob\StackmobException; use Stackmob\LoginSessionExpiredException; From 31065ccabbda00a7e1d7d584a8f6b42cf8213520 Mon Sep 17 00:00:00 2001 From: Federico Freire Date: Wed, 21 Aug 2013 16:10:32 -0500 Subject: [PATCH 17/29] Namespaces references added. --- src/Stackmob/CustomCode.php | 2 ++ src/Stackmob/Object.php | 8 ++++++-- src/Stackmob/Push.php | 4 +++- src/Stackmob/Query.php | 11 ++++++++--- src/Stackmob/Rest.php | 3 ++- src/Stackmob/User.php | 5 ++++- 6 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/Stackmob/CustomCode.php b/src/Stackmob/CustomCode.php index 5de452f..bbb1265 100644 --- a/src/Stackmob/CustomCode.php +++ b/src/Stackmob/CustomCode.php @@ -5,6 +5,8 @@ namespace Stackmob; +use Stackmob\Rest; + class CustomCode extends Stackmob { const API_PATH = 'http://api.mob1.stackmob.com/'; diff --git a/src/Stackmob/Object.php b/src/Stackmob/Object.php index 31670a5..5a25cad 100644 --- a/src/Stackmob/Object.php +++ b/src/Stackmob/Object.php @@ -8,6 +8,10 @@ namespace Stackmob; +use Stackmob\DummyLogger; +use Stackmob\Rest; +use Stackmob\Object; + class Object { //put your code here @@ -72,10 +76,10 @@ public function __construct($objectClass,$attributes=array(), $pk=null){ $this->attributes($attributes); // TODO: Fix the use of many rest clients - $this->_rest = new \Stackmob\Rest(); + $this->_rest = new Rest(); if(!Object::$_restClient){ - Object::$_restClient = new \Stackmob\Rest(); + Object::$_restClient = new Rest(); } $this->initialize(); diff --git a/src/Stackmob/Push.php b/src/Stackmob/Push.php index 810aa31..00a68b5 100644 --- a/src/Stackmob/Push.php +++ b/src/Stackmob/Push.php @@ -4,6 +4,8 @@ */ namespace Stackmob; +use Stackmob\Rest; + class Push { /** @@ -21,7 +23,7 @@ class Push { public static function send($data, $users = array()){ if(!Push::$_restClient){ - Push::$_restClient = new \Stackmob\Rest(); + Push::$_restClient = new Rest(); } return Push::$_restClient->push($data, $users); diff --git a/src/Stackmob/Query.php b/src/Stackmob/Query.php index 204efb5..d7d0090 100644 --- a/src/Stackmob/Query.php +++ b/src/Stackmob/Query.php @@ -8,6 +8,11 @@ namespace Stackmob; +use Stackmob\DummyLogger; +use Stackmob\User; +use Stackmob\Rest; +use Stackmob\Object; + class Query extends Object { protected $_pk = null; @@ -30,7 +35,7 @@ public function __construct($objectClass, $pk = null){ $this->objectClass = $objectClass; $this->_pk = $pk ? $pk : strtolower($objectClass) . '_id'; - $this->_rest = new \Stackmob\Rest(); + $this->_rest = new Rest(); } @@ -203,9 +208,9 @@ public function find(){ } if($this->objectClass == Object::USER_OBJECT_CLASS){ - $objects[$index] = new \Stackmob\User($attributes); + $objects[$index] = new User($attributes); }else{ - $objects[$index] = new \Stackmob\Object($this->objectClass,$attributes); + $objects[$index] = new Object($this->objectClass,$attributes); } } } diff --git a/src/Stackmob/Rest.php b/src/Stackmob/Rest.php index 59b3853..2139e68 100644 --- a/src/Stackmob/Rest.php +++ b/src/Stackmob/Rest.php @@ -8,6 +8,7 @@ use Stackmob\OAuth2Signer; use Stackmob\StackmobException; use Stackmob\LoginSessionExpiredException; +use Stackmob\DummyLogger; use OAuth\OAuthConsumer; use OAuth\OAuthSignatureMethodHMACSHA1; @@ -698,7 +699,7 @@ protected function request($path,$method,$postData=array(),$headers=null){ $request = OAuthRequest::from_consumer_and_token($this->_oauthConsumer, NULL, $method, $endpoint, $params); // Sign the constructed OAuth request using HMAC-SHA1 - Use NULL for OAuthToken parameter - $request->sign_request(new OAuthSignatureMethod_HMAC_SHA1(), $this->_oauthConsumer, NULL); + $request->sign_request(new OAuthSignatureMethodHMACSHA1(), $this->_oauthConsumer, NULL); // Extract OAuth header from OAuth request object and keep it handy in a variable $oauth_header = $request->to_header(); diff --git a/src/Stackmob/User.php b/src/Stackmob/User.php index 7d4920c..0136c1a 100644 --- a/src/Stackmob/User.php +++ b/src/Stackmob/User.php @@ -4,6 +4,9 @@ */ namespace Stackmob; +use Stackmob\User; +use Stackmob\Rest; + class User extends Object { // Class /////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -53,7 +56,7 @@ public static function requestPasswordReset($email){ */ public static function signUpUser($username, $password, $attributes=array()){ if(!Object::$_restClient){ - Object::$_restClient = new \Stackmob\Rest(); + Object::$_restClient = new Rest(); } $user = null; From 49921c491a47e6840504454e288c90c01ea3fd7e Mon Sep 17 00:00:00 2001 From: Federico Freire Date: Wed, 21 Aug 2013 16:21:19 -0500 Subject: [PATCH 18/29] Missing namespace use un Rest --- src/Stackmob/Rest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Stackmob/Rest.php b/src/Stackmob/Rest.php index 2139e68..ff948f8 100644 --- a/src/Stackmob/Rest.php +++ b/src/Stackmob/Rest.php @@ -11,6 +11,7 @@ use Stackmob\DummyLogger; use OAuth\OAuthConsumer; +use OAuth\OAuthRequest; use OAuth\OAuthSignatureMethodHMACSHA1; class Rest { From b9f0989da392622f85ec564fed91f202dbf4b525 Mon Sep 17 00:00:00 2001 From: Federico Freire Date: Mon, 26 Aug 2013 01:23:20 -0500 Subject: [PATCH 19/29] Query class fixed to expect single object in the response. --- src/Stackmob/Query.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Stackmob/Query.php b/src/Stackmob/Query.php index d7d0090..8ccd688 100644 --- a/src/Stackmob/Query.php +++ b/src/Stackmob/Query.php @@ -198,8 +198,12 @@ public function find(){ if($this->_rest->statusCode() == 200){ $this->_count = $this->_rest->count(); $indexKey = $this->indexKey; - if(!is_array($found)) - return array(); + + // if the result is a single object (for example, in the case of listapi + // query), it's converted to an array before being processed + if(!is_array($found)) { + $found = array($found); + } foreach($found as $attributes){ if($indexKey){ $index = isset($attributes->$indexKey) ? $attributes->$indexKey : count($objects); From 93ff95d08b26e13ecef39ee8f167700af23de281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?I=C3=B1aki=20Abete?= Date: Fri, 30 Aug 2013 19:41:59 -0300 Subject: [PATCH 20/29] Update composer.json --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 4119603..702e020 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "productgram/stackmobphp", + "name": "inakiabt/stackmobphp", "description": "Simple PHP API for Stackmob based on inakiabt/stackmob project", "license": "MIT", "authors": [ @@ -15,12 +15,12 @@ "repositories": [ { "type": "vcs", - "url": "git@bitbucket.org:productgram/pgf_oauth.git" + "url": "git@github.com:fefuts/oauth.git" } ], "require": { "php": ">=5.3.0", - "productgram/pgf_oauth": "dev-master" + "fefuts/oauth": "dev-master" }, "require-dev": { "phpunit/phpunit": "3.7.5", From 216385dd7b534257e820997058a284ee640c1454 Mon Sep 17 00:00:00 2001 From: Federico Freire Date: Fri, 30 Aug 2013 20:46:24 -0500 Subject: [PATCH 21/29] Rest class is now configured by new Configuration class. --- composer.json | 4 +- src/Stackmob/Configuration.php | 63 +++++++++++++++ src/Stackmob/Rest.php | 40 +++++---- src/Tests/StackmobFactoryTest.php | 30 +++++++ tests/Stackmob/ObjectTest.php | 47 ----------- tests/Stackmob/QueryTest.php | 130 ------------------------------ tests/Stackmob/UserTest.php | 102 ----------------------- tests/phpunit.xml | 21 ----- tests/readme.md | 10 --- 9 files changed, 118 insertions(+), 329 deletions(-) create mode 100644 src/Stackmob/Configuration.php create mode 100644 src/Tests/StackmobFactoryTest.php delete mode 100644 tests/Stackmob/ObjectTest.php delete mode 100644 tests/Stackmob/QueryTest.php delete mode 100644 tests/Stackmob/UserTest.php delete mode 100644 tests/phpunit.xml delete mode 100644 tests/readme.md diff --git a/composer.json b/composer.json index 4119603..ee59144 100644 --- a/composer.json +++ b/composer.json @@ -15,12 +15,12 @@ "repositories": [ { "type": "vcs", - "url": "git@bitbucket.org:productgram/pgf_oauth.git" + "url": "git@github.com:fefuts/oauth.git" } ], "require": { "php": ">=5.3.0", - "productgram/pgf_oauth": "dev-master" + "fefuts/oauth": "dev-master" }, "require-dev": { "phpunit/phpunit": "3.7.5", diff --git a/src/Stackmob/Configuration.php b/src/Stackmob/Configuration.php new file mode 100644 index 0000000..d068fba --- /dev/null +++ b/src/Stackmob/Configuration.php @@ -0,0 +1,63 @@ + +*/ + +namespace Stackmob; + +class Configuration +{ + private static $key; + private static $secret; + private static $logger; + private static $environment = 'dev'; + + public static function getKey() + { + if (empty(self::$key)) { + throw new \Exception(__METHOD__ . " - Stackmob key must be set.", 1); + + } + return self::$key; + } + + public static function setKey($key) + { + self::$key = $key; + } + + public static function getSecret() + { + if (empty(self::$secret)) { + throw new \Exception(__METHOD__ . " - Stackmob secret must be set.", 1); + + } + return self::$secret; + } + + public static function setSecret($secret) + { + self::$secret = $secret; + } + + public static function getLogger() + { + return self::$logger; + } + + public static function setLogger($logger) + { + self::$logger = $logger; + } + + public static function getEnvironment() + { + return self::$environment; + } + + public static function setEnvironment($environment) + { + self::$environment = $environment; + } +} \ No newline at end of file diff --git a/src/Stackmob/Rest.php b/src/Stackmob/Rest.php index ff948f8..ae314dd 100644 --- a/src/Stackmob/Rest.php +++ b/src/Stackmob/Rest.php @@ -9,18 +9,14 @@ use Stackmob\StackmobException; use Stackmob\LoginSessionExpiredException; use Stackmob\DummyLogger; +use Stackmob\Configuration; use OAuth\OAuthConsumer; use OAuth\OAuthRequest; use OAuth\OAuthSignatureMethodHMACSHA1; -class Rest { - - public static $consumerKey; - public static $consumerSecret; - public static $DEVELOPMENT = true; // default development, false is production - private static $oldConsumerKey; - private static $oldConsumerSecret; +class Rest +{ const API_URL = 'https://api.stackmob.com'; const USER_AGENT = 'StackmobRest/0.1'; const OBJECT_PATH_PREFIX = ''; @@ -46,11 +42,12 @@ class Rest { protected $_apiUrl; protected $_isSecure; protected $log; + protected $environment; public function __construct($apiUrl = null) { $this->_apiUrl = $apiUrl ? $apiUrl : Rest::API_URL; $this->_isSecure = Rest::startsWith($this->_apiUrl, "https"); - $this->_oauthConsumer = new OAuthConsumer(Rest::$consumerKey, Rest::$consumerSecret, NULL); + $this->_oauthConsumer = new OAuthConsumer(Configuration::getKey(), Configuration::getSecret(), NULL); // just to make sure the logging does not fails if used before setUpLog $this->log = new DummyLogger(); @@ -461,6 +458,15 @@ protected function strVarDump($var) { return $dump; } + protected function getVersion() + { + return ($this->environment === 'prod') ? 1 : 0; + } + + protected function isProductionEnvironment() + { + return ($this->environment === 'prod'); + } /** * @@ -471,7 +477,7 @@ protected function strVarDump($var) { * @return type */ protected function loginRequest($path,$postData=array(),$headers=null){ - $version = Rest::$DEVELOPMENT ? 0 : 1; + $version = $this->getVersion(); $postData['token_type'] = 'mac'; // So that it returns the right thing $endpoint = $this->_apiUrl.'/'.$path; $this->log->debug( "endpoint: " . $endpoint . ""); @@ -479,13 +485,13 @@ protected function loginRequest($path,$postData=array(),$headers=null){ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_FAILONERROR, true); // Don't verify peer in developer mode - curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, !Rest::$DEVELOPMENT); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, $this->isProductionEnvironment()); curl_setopt($curl, CURLOPT_HEADER, true); curl_setopt($curl, CURLOPT_HTTPHEADER, array( 'Content-Type: application/x-www-form-urlencoded;', 'Content-Length: '.strlen(http_build_query($postData)), "Accept: application/vnd.stackmob+json; version=$version", - "X-StackMob-API-Key: " . Rest::$consumerKey, + "X-StackMob-API-Key: " . Configuration::getKey(), "X-Stackmob-User-Agent: stackmobphp 0.1")); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($postData)); @@ -560,12 +566,12 @@ function processPostData($postData) } function send_request($http_method, $url, $auth_header=null, $postData=null, $headers=null) { - $version = Rest::$DEVELOPMENT ? 0 : 1; + $version = $this->getVersion(); $curl = curl_init($url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // curl_setopt($curl, CURLOPT_FAILONERROR, true); // Don't verify peer in developer mode - curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, !Rest::$DEVELOPMENT); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, $this->isProductionEnvironment()); curl_setopt($curl, CURLOPT_HEADER, false); if (is_array($postData)) @@ -586,7 +592,7 @@ function send_request($http_method, $url, $auth_header=null, $postData=null, $he curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-Type: application/vnd.stackmob+json;", 'Content-Length: 0', "Accept: application/vnd.stackmob+json; version=$version", - "X-StackMob-API-Key: " . Rest::$consumerKey, + "X-StackMob-API-Key: " . Configuration::getKey(), "X-Stackmob-User-Agent: stackmobphp 0.1", $headers, $auth_header)); @@ -596,7 +602,7 @@ function send_request($http_method, $url, $auth_header=null, $postData=null, $he 'Content-Type: application/json', 'Content-Length: '.strlen(json_encode($postData)), "Accept: application/vnd.stackmob+json; version=$version", - "X-StackMob-API-Key: " . Rest::$consumerKey, + "X-StackMob-API-Key: " . Configuration::getKey(), "X-Stackmob-User-Agent: stackmobphp 0.1", $headers, $auth_header)); @@ -608,7 +614,7 @@ function send_request($http_method, $url, $auth_header=null, $postData=null, $he 'Content-Type: application/json', 'Content-Length: '.strlen(json_encode($postData)), "Accept: application/vnd.stackmob+json; version=$version", - "X-StackMob-API-Key: " . Rest::$consumerKey, + "X-StackMob-API-Key: " . Configuration::getKey(), "X-Stackmob-User-Agent: stackmobphp 0.1", $headers, $auth_header)); @@ -620,7 +626,7 @@ function send_request($http_method, $url, $auth_header=null, $postData=null, $he "Content-Type: application/json", 'Content-Length: 0', "Accept: application/vnd.stackmob+json; version=$version", - "X-StackMob-API-Key: " . Rest::$consumerKey, + "X-StackMob-API-Key: " . Configuration::getKey(), "X-Stackmob-User-Agent: stackmobphp 0.1", $headers, $auth_header)); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $http_method); diff --git a/src/Tests/StackmobFactoryTest.php b/src/Tests/StackmobFactoryTest.php new file mode 100644 index 0000000..edc2433 --- /dev/null +++ b/src/Tests/StackmobFactoryTest.php @@ -0,0 +1,30 @@ + 'id')); +$o->fetch(); +var_dump($o); + +$user = new User(array('username' => 'user_name')); +$user->fetch(); +var_dump($user); + +$query = new Query('product'); +$query->isEqual('field_name','value'); +$results = $query->find(); +$count = count($results); +var_dump($count); diff --git a/tests/Stackmob/ObjectTest.php b/tests/Stackmob/ObjectTest.php deleted file mode 100644 index a6bf67e..0000000 --- a/tests/Stackmob/ObjectTest.php +++ /dev/null @@ -1,47 +0,0 @@ -objects = array(); - $object1 = new Object('Flimmy', array('flimLevel' => 5, // TODO: camel case should convert to underscore - 'flimtackular' => false, 'flammy' => 'blammy')); - $object1->save(); - $this->objects[] = $object1; - - $object2 = new Object('Flimmy', - array('flimLevel' => 7, 'flimtackular' => true, 'flammy' => 'slammy')); - $object2->save(); - $this->objects[] = $object1; - - - } - - public function tearDown() { - parent::tearDown(); - $this->user->delete(); - foreach($this->objects as $object) - $object->delete(); - } -} - -?> diff --git a/tests/Stackmob/QueryTest.php b/tests/Stackmob/QueryTest.php deleted file mode 100644 index cdb87d6..0000000 --- a/tests/Stackmob/QueryTest.php +++ /dev/null @@ -1,130 +0,0 @@ -log = new DummyLogger(); - $user = new User(array("username" => "jimbo", "password" => "123456", "age" => 25)); - $user->signUp(); - - // Set up test objects - - $object1 = new Object('Flimmy', array('flimlevel' => 5, // TODO: camel case should convert to underscore - 'flimtackular' => false)); - $object1->save(); - - $object2 = new Object('Flimmy', array('flimlevel' => 7, 'flimtackular' => true, 'flammy' => 'slammy')); - $object2->save(); - } - - public function tearDown() { - parent::tearDown(); - $user = new User(array("username" => "jimbo", "password" => "123456")); - $user->logIn(); - - $q = new Query("Flimmy"); - $objects = $q->find(); - foreach ($objects as $object) { - $object->delete(); - } - - $user->delete(); - } - - public function testObjectFetchWithEquals() { - $this->log->debug("testObjectFetchWithEquals"); - $user = new User(array("username" => "jimbo", "password" => "123456")); - $user->logIn(); - $query = new Query('Flimmy'); - $query->isEqual('flimlevel', 7); - - $results = $query->find(); - $this->assertEquals(1, count($results)); - $flim = $results[0]; - $this->assertEquals(7, $flim->get('flimlevel')); - } - - public function testObjectFetchIsNull() { - $this->log->debug("testObjectFetchIsNull"); - $user = new User(array("username" => "jimbo", "password" => "123456")); - $user->logIn(); - $query = new Query('Flimmy'); - $query->isNull('flammy'); - - $results = $query->find(); - $this->assertEquals(1, count($results)); - $flim = $results[0]; - $this->assertEquals(7, $flim->get('flimlevel')); - } - - public function testUserFetchWithAgeEquals() { - $this->log->debug("testUserFetchWithAgeEquals"); - $user = new User(array("username" => "jimbo", "password" => "123456")); - $user->logIn(); - $query = new Query('User'); - $query->isEqual('age', 25); - $results = $query->find(); - $this->assertEquals(1, count($results)); - $user = $results[0]; - - $this->assertEquals("jimbo", $user->getUsername()); - $this->assertArrayHasKey("createddate", $user->attributes()); - $this->assertArrayHasKey("lastmoddate", $user->attributes()); - $this->assertArrayHasKey("sm_owner", $user->attributes()); - $this->assertEquals("25", $user->get("age")); - } - - public function testUserFetchWithAgeLessThan() { - $this->log->debug("testUserFetchWithAgeLessThan"); - $user = new User(array("username" => "jimbo", "password" => "123456")); - $user->logIn(); - $query = new Query('User'); - $query->lessThan('age', 26); - $results = $query->find(); - $this->assertEquals(1, count($results)); - $user = $results[0]; - - $this->assertEquals("jimbo", $user->getUsername()); - $this->assertArrayHasKey("createddate", $user->attributes()); - $this->assertArrayHasKey("lastmoddate", $user->attributes()); - $this->assertArrayHasKey("sm_owner", $user->attributes()); - $this->assertEquals("25", $user->get("age")); - - } - - public function testUserFetchWithAgeGreaterThan() { - $this->log->debug("testUserFetchWithAgeLessThan"); - $user = new User(array("username" => "jimbo", "password" => "123456")); - $user->logIn(); - $query = new Query('User'); - $query->greaterThan('age', 20); - $results = $query->find(); - $this->assertEquals(1, count($results)); - $user = $results[0]; - - $this->assertEquals("jimbo", $user->getUsername()); - $this->assertArrayHasKey("createddate", $user->attributes()); - $this->assertArrayHasKey("lastmoddate", $user->attributes()); - $this->assertArrayHasKey("sm_owner", $user->attributes()); - $this->assertEquals("25", $user->get("age")); - - } - -} - -?> diff --git a/tests/Stackmob/UserTest.php b/tests/Stackmob/UserTest.php deleted file mode 100644 index e7914c7..0000000 --- a/tests/Stackmob/UserTest.php +++ /dev/null @@ -1,102 +0,0 @@ -log = new DummyLogger(); - $this->log->debug("TEST: PHPVERSION" . PHP_VERSION); - } - - - public function testSignupUserStatic() { - $this->log->debug("testSignupUserStatic"); - $user = User::signUpUser("jimbo", "123456"); - $user->set("age", 25); - $this->assertEquals("jimbo", $user->getUsername()); - $this->assertArrayHasKey("createddate", $user->attributes()); - $this->assertArrayHasKey("lastmoddate", $user->attributes()); - $this->assertArrayHasKey("sm_owner", $user->attributes()); - } - - public function testLoginUserSuccess() { - $this->log->debug("testLoginUserSuccess"); - $user = new User(array("username" => "jimbo", "password" => "123456")); - $user->logIn(); - $this->assertArrayHasKey("lastmoddate", $user->attributes()); - $this->assertArrayHasKey("createddate", $user->attributes()); - session_destroy(); - } - - public function testLoginCreateObjectOwner() { - $this->log->debug("testLoginCreateObjectOwner"); - $user = new User(array("username" => "jimbo", "password" => "123456")); - $user->logIn(); - - $flimmy = new Object("Flimmy", array("flimlevel" => 5)); - $flimmy->save(); - $this->assertEquals("user/jimbo", $flimmy->get('sm_owner')); - $flimmy->delete(); - } - - - public function testDeleteUser() { - $this->log->debug("testDeleteUser"); - $user = new User(array("username" => "jimbo")); - $user->delete(); - try { - $user->fetch(); - } catch(\Stackmob\StackmobException $e) { - $this->assertEquals('The requested URL returned error: 404 Not Found', $e->getMessage()); - } - } - - /** - * @expectedException \Stackmob\StackmobException - */ - public function testLoginFailedException() { - $this->log->debug("testLoginFailedException"); - - $user = new User(); - $user->logIn("jimbo", "23423423423"); - } - - - - public function testSignupUserNonStatic() { - $this->log->debug("testSignupUserNonStatic"); - $user = new User(array("username" => "jimbo", "password" => "123456")); - $user->signUp(); - $this->assertArrayHasKey("createddate", $user->attributes()); - $this->assertArrayHasKey("lastmoddate", $user->attributes()); - $this->assertArrayHasKey("sm_owner", $user->attributes()); - } - - public function testFetchUser() { - $this->log->debug("testFetchUser"); - $user = new User(array("username" => "jimbo")); - $user->fetch(); - $this->assertArrayHasKey("createddate", $user->attributes()); - $this->assertArrayHasKey("lastmoddate", $user->attributes()); - $this->assertArrayHasKey("sm_owner", $user->attributes()); - $user->delete(); // clean up - } - -} - -?> diff --git a/tests/phpunit.xml b/tests/phpunit.xml deleted file mode 100644 index 0c34ffb..0000000 --- a/tests/phpunit.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - ./Stackmob/ - - - - - - ../src/Stackmob - - - diff --git a/tests/readme.md b/tests/readme.md deleted file mode 100644 index c17b0d8..0000000 --- a/tests/readme.md +++ /dev/null @@ -1,10 +0,0 @@ -#Tests - -## Running tests - -To run tests: - -```` -> cd Stackmob -> ../../vendor/bin/phpunit --stderr ObjectTest.php -> # logs will be in sm.log From 25f1d38fb613d2c3a8e1bc7d6281ddc68b331052 Mon Sep 17 00:00:00 2001 From: Federico Freire Date: Sun, 1 Sep 2013 13:12:48 -0500 Subject: [PATCH 22/29] Configuration logger getter replaced in Rest, Object and Query classes. --- src/Stackmob/Object.php | 16 ++-------------- src/Stackmob/Query.php | 4 ++-- src/Stackmob/Rest.php | 12 +----------- 3 files changed, 5 insertions(+), 27 deletions(-) diff --git a/src/Stackmob/Object.php b/src/Stackmob/Object.php index 5a25cad..26f7ecb 100644 --- a/src/Stackmob/Object.php +++ b/src/Stackmob/Object.php @@ -8,9 +8,9 @@ namespace Stackmob; -use Stackmob\DummyLogger; use Stackmob\Rest; use Stackmob\Object; +use Stackmob\Configuration; class Object { //put your code here @@ -46,18 +46,6 @@ public static function saveAll($list){ } } - /** - * Public, so its inherited. - */ - public function setUpLog($logger) - { - if (empty($logger)) { - return; - } - - $this->log = $logger; - } - /** * Constructor * Creates a new model with defined attributes. @@ -69,7 +57,7 @@ public function setUpLog($logger) public function __construct($objectClass,$attributes=array(), $pk=null){ // just to make sure the logging does not fails if used before setUpLog - $this->log = new DummyLogger(); + $this->log = Configuration::getLogger(); $this->objectClass = $objectClass; $this->_pk = $pk ? $pk : strtolower($objectClass) . '_id'; diff --git a/src/Stackmob/Query.php b/src/Stackmob/Query.php index 8ccd688..3ee8e62 100644 --- a/src/Stackmob/Query.php +++ b/src/Stackmob/Query.php @@ -8,7 +8,7 @@ namespace Stackmob; -use Stackmob\DummyLogger; +use Stackmob\Configuration; use Stackmob\User; use Stackmob\Rest; use Stackmob\Object; @@ -30,7 +30,7 @@ class Query extends Object { * @param type $pk */ public function __construct($objectClass, $pk = null){ - $this->log = new DummyLogger(); + $this->log = Configuration::getLogger(); $this->objectClass = $objectClass; $this->_pk = $pk ? $pk : strtolower($objectClass) . '_id'; diff --git a/src/Stackmob/Rest.php b/src/Stackmob/Rest.php index ae314dd..366a7c6 100644 --- a/src/Stackmob/Rest.php +++ b/src/Stackmob/Rest.php @@ -8,7 +8,6 @@ use Stackmob\OAuth2Signer; use Stackmob\StackmobException; use Stackmob\LoginSessionExpiredException; -use Stackmob\DummyLogger; use Stackmob\Configuration; use OAuth\OAuthConsumer; @@ -50,16 +49,7 @@ public function __construct($apiUrl = null) { $this->_oauthConsumer = new OAuthConsumer(Configuration::getKey(), Configuration::getSecret(), NULL); // just to make sure the logging does not fails if used before setUpLog - $this->log = new DummyLogger(); - } - - public function setUpLog($logger) - { - if (empty($logger)) { - return; - } - - $this->log = $logger; + $this->log = Configuration::getLogger(); $this->log->debug(__CLASS__ . " - Is Secure: " . $this->_isSecure); $this->log->debug(__CLASS__ . " - apiUrl: " . $this->_apiUrl); } From 12bbefba7fc589015335fe1a8b6f08a4bf85164b Mon Sep 17 00:00:00 2001 From: Federico Freire Date: Sun, 1 Sep 2013 18:47:48 -0500 Subject: [PATCH 23/29] getVersion method added to Configuration class. --- src/Stackmob/Configuration.php | 5 +++++ src/Stackmob/Rest.php | 9 ++------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Stackmob/Configuration.php b/src/Stackmob/Configuration.php index d068fba..26bc071 100644 --- a/src/Stackmob/Configuration.php +++ b/src/Stackmob/Configuration.php @@ -60,4 +60,9 @@ public static function setEnvironment($environment) { self::$environment = $environment; } + + public static getVersion() + { + return (self::$environment === 'prod') ? 1 : 0; + } } \ No newline at end of file diff --git a/src/Stackmob/Rest.php b/src/Stackmob/Rest.php index 366a7c6..efaf9ab 100644 --- a/src/Stackmob/Rest.php +++ b/src/Stackmob/Rest.php @@ -448,11 +448,6 @@ protected function strVarDump($var) { return $dump; } - protected function getVersion() - { - return ($this->environment === 'prod') ? 1 : 0; - } - protected function isProductionEnvironment() { return ($this->environment === 'prod'); @@ -467,7 +462,7 @@ protected function isProductionEnvironment() * @return type */ protected function loginRequest($path,$postData=array(),$headers=null){ - $version = $this->getVersion(); + $version = Configuration::getVersion(); $postData['token_type'] = 'mac'; // So that it returns the right thing $endpoint = $this->_apiUrl.'/'.$path; $this->log->debug( "endpoint: " . $endpoint . ""); @@ -556,7 +551,7 @@ function processPostData($postData) } function send_request($http_method, $url, $auth_header=null, $postData=null, $headers=null) { - $version = $this->getVersion(); + $version = Configuration::getVersion(); $curl = curl_init($url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // curl_setopt($curl, CURLOPT_FAILONERROR, true); From 159e5c9be922b4c94450484e780769cc85cbd554 Mon Sep 17 00:00:00 2001 From: Federico Freire Date: Sun, 1 Sep 2013 19:31:05 -0500 Subject: [PATCH 24/29] Fixed getVersion signature in Configuration class. --- src/Stackmob/Configuration.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stackmob/Configuration.php b/src/Stackmob/Configuration.php index 26bc071..1572d2e 100644 --- a/src/Stackmob/Configuration.php +++ b/src/Stackmob/Configuration.php @@ -61,7 +61,7 @@ public static function setEnvironment($environment) self::$environment = $environment; } - public static getVersion() + public static function getVersion() { return (self::$environment === 'prod') ? 1 : 0; } From 87a2b776587bd4434b965cb28f8f9d3c4a5cb168 Mon Sep 17 00:00:00 2001 From: Federico Freire Date: Mon, 2 Sep 2013 01:28:33 -0500 Subject: [PATCH 25/29] Depth parameter added to Rest::getObject method. --- src/Stackmob/Rest.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Stackmob/Rest.php b/src/Stackmob/Rest.php index efaf9ab..4fd64bb 100644 --- a/src/Stackmob/Rest.php +++ b/src/Stackmob/Rest.php @@ -84,10 +84,11 @@ public function getObjects($objectClass,$params=array(),$selects=null,$order=nul * * @param $objectClass * @param $objectId + * @param $depth * @return array */ - public function getObject($objectClass,$objectId){ - $path = $this->objectPath($objectClass,$objectId); + public function getObject($objectClass, $objectId, $depth){ + $path = $this->objectPath($objectClass,$objectId, $depth); return $this->get($path); } From 667b5c4663c07203e70ccc1f5d4d2384ef27cb2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?I=C3=B1aki=20Abete?= Date: Tue, 24 Sep 2013 03:22:51 -0500 Subject: [PATCH 26/29] Add DummyLogger as default logger --- src/Stackmob/Configuration.php | 4 ++++ src/Stackmob/DummyLogger.php | 14 +++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/Stackmob/Configuration.php b/src/Stackmob/Configuration.php index 1572d2e..8c5c9c3 100644 --- a/src/Stackmob/Configuration.php +++ b/src/Stackmob/Configuration.php @@ -43,6 +43,10 @@ public static function setSecret($secret) public static function getLogger() { + if (self::$logger === NULL) + { + self::$logger = new DummyLogger(); + } return self::$logger; } diff --git a/src/Stackmob/DummyLogger.php b/src/Stackmob/DummyLogger.php index 3eaa8d9..99571af 100644 --- a/src/Stackmob/DummyLogger.php +++ b/src/Stackmob/DummyLogger.php @@ -9,7 +9,19 @@ class DummyLogger { - public function debug() + public function info($msg, $other = null) + { + } + public function critical($msg, $other = null) + { + } + public function warn($msg, $other = null) + { + } + public function error($msg, $other = null) + { + } + public function debug($msg, $other = null) { } } \ No newline at end of file From ee0f3d12e133a524e74fe7afdb1261a1f155f353 Mon Sep 17 00:00:00 2001 From: Federico Freire Date: Tue, 15 Oct 2013 01:32:20 -0500 Subject: [PATCH 27/29] Depth parameter added to Query. --- src/Stackmob/Query.php | 66 ++++++++++++++++++++---------------------- src/Stackmob/Rest.php | 61 +++++++++++++++++++++----------------- src/Stackmob/User.php | 18 ++++++------ 3 files changed, 74 insertions(+), 71 deletions(-) diff --git a/src/Stackmob/Query.php b/src/Stackmob/Query.php index 3ee8e62..ac45f6d 100644 --- a/src/Stackmob/Query.php +++ b/src/Stackmob/Query.php @@ -22,10 +22,10 @@ class Query extends Object { protected $_depth = null; protected $_rest = null; protected $_range = null; - + /** - * + * * @param type $objectClass * @param type $pk */ @@ -38,20 +38,20 @@ public function __construct($objectClass, $pk = null){ $this->_rest = new Rest(); } - + /** * https://developer.stackmob.com/sdks/rest/api#a-equality_query - * + * * @param type $key * @param type $value */ public function isEqual($key, $value) { $this->_where[$key] = $value; } - + /** * https://developer.stackmob.com/sdks/rest/api#a-inequality_queries____________________null_ - * + * * @param type $key * @param type $value */ @@ -61,27 +61,27 @@ public function notEqual($key, $value) { /** * https://developer.stackmob.com/sdks/rest/api#a-inequality_queries____________________null_ - * + * * @param type $key * @param type $value */ - public function greaterThan($key, $value) { + public function greaterThan($key, $value) { $this->setWhereKeyHashValue($key, 'gt', $value); } /** * https://developer.stackmob.com/sdks/rest/api#a-inequality_queries____________________null_ - * + * * @param type $key * @param type $value */ - public function lessThan($key, $value) { + public function lessThan($key, $value) { $this->setWhereKeyHashValue($key, 'lt', $value); } /** * https://developer.stackmob.com/sdks/rest/api#a-equality_query - * + * * @param type $key */ public function notNull($key) { @@ -90,7 +90,7 @@ public function notNull($key) { /** * https://developer.stackmob.com/sdks/rest/api#a-equality_query - * + * * @param type $key */ public function isNull($key) { @@ -100,7 +100,7 @@ public function isNull($key) { /** * https://developer.stackmob.com/sdks/rest/api#a-querying_for_multiple_values * https://developer.stackmob.com/sdks/rest/api#a-querying_arrays - * + * * @param type $key * @param type $values */ @@ -110,7 +110,7 @@ public function in($key, $values) { /** * https://developer.stackmob.com/sdks/rest/api#a-get_-_expanding_relationships:_get_full_objects__not_just_ids - * + * * @param type $value */ public function depth($value) { @@ -119,7 +119,7 @@ public function depth($value) { /** * https://developer.stackmob.com/sdks/rest/api#a-selecting_fields_to_return - * + * * @param type $values */ public function select($values=array()) { @@ -128,7 +128,7 @@ public function select($values=array()) { /** * https://developer.stackmob.com/sdks/rest/api#a-order_by - * + * * @param type $values */ public function asc($values=array()) { @@ -137,18 +137,18 @@ public function asc($values=array()) { /** * https://developer.stackmob.com/sdks/rest/api#a-order_by - * + * * @param type $values */ public function desc($values=array()) { $this->_orderby['desc'] = $values; } - + /** * Pagination - * + * * https://developer.stackmob.com/sdks/rest/api#a-pagination - * + * * @param type $low * @param type $high * @return boolean @@ -159,22 +159,22 @@ public function range($low, $high) { } else { return false; } - + return true; } - + /** * Limit - * + * * https://developer.stackmob.com/sdks/rest/api#a-pagination - * + * * @param type $max */ public function limit($max) { return $this->range(0, $max); } - - + + /** * Retrieves a list of Stackmob Objects that satisfy this query. * @@ -182,10 +182,6 @@ public function limit($max) { */ public function find(){ - if($this->_depth) { - $this->_where[] = array("_expand" => $this->_depth); - } - $params = $this->_where; $selects = $this->preparedSelects(); $order = $this->preparedOrderBy(); @@ -234,7 +230,7 @@ protected function _find($params,$selects=null,$order=null,$range=null,$depth=nu } /** - * + * * @return string */ protected function preparedOrderBy() { @@ -247,15 +243,15 @@ protected function preparedOrderBy() { foreach($this->_orderBy['desc'] as $item) { $order[] = "$item:desc"; } - + $order = "X-StackMob-OrderBy:" . implode(',',$order); } - + return $order; } - + /** - * + * * @return string */ protected function preparedSelects() { diff --git a/src/Stackmob/Rest.php b/src/Stackmob/Rest.php index 4fd64bb..3343fbe 100644 --- a/src/Stackmob/Rest.php +++ b/src/Stackmob/Rest.php @@ -14,7 +14,7 @@ use OAuth\OAuthRequest; use OAuth\OAuthSignatureMethodHMACSHA1; -class Rest +class Rest { const API_URL = 'https://api.stackmob.com'; const USER_AGENT = 'StackmobRest/0.1'; @@ -42,7 +42,7 @@ class Rest protected $_isSecure; protected $log; protected $environment; - + public function __construct($apiUrl = null) { $this->_apiUrl = $apiUrl ? $apiUrl : Rest::API_URL; $this->_isSecure = Rest::startsWith($this->_apiUrl, "https"); @@ -59,8 +59,8 @@ public static function startsWith($haystack, $needle) $length = strlen($needle); return (substr($haystack, 0, $length) === $needle); } - - + + // Convenience Methods for Objects, Users, Push Notifications // Objects ///////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -74,8 +74,8 @@ public static function startsWith($haystack, $needle) * @return array */ public function getObjects($objectClass,$params=array(),$selects=null,$order=null,$range=null,$depth=null){ - $path = $this->objectPath($objectClass); - return $this->get($path,$params,$selects,$order,$range,$depth); + $path = $this->objectPath($objectClass, null, $depth); + return $this->get($path,$params,$selects,$order,$range); } /** @@ -106,9 +106,9 @@ public function createObject($objectClass,$data){ } /** - * + * * https://developer.stackmob.com/sdks/rest/api#a-post_-_creating_and_appending_related_objects - * + * * @param type $objectClass * @param type $id * @param type $relateClass @@ -121,9 +121,9 @@ protected function relateAndCreate($objectClass, $id, $relateClass, $data) { return $this->post($path,$data); } /** - * + * * https://developer.stackmob.com/sdks/rest/api#a-put_-_appending_values_to_an_array_or_add_an_existing_object_to_a_relationship - * + * * @param type $objectClass * @param type $id * @param type $relateClass @@ -136,7 +136,7 @@ protected function relate($objectClass, $id, $relateClass, $relateId) { $data = array ($relateClass . '_id' => $relateId); return $this->put($path, $data); } - + /** * PUT Object * @url https://developer.stackmob.com/sdks/rest/api#a-put_-_update_object @@ -208,7 +208,7 @@ public function push($payload,$users=array()){ /** * GET Users * @url https://developer.stackmob.com/sdks/rest/api#a-get_-_read_objects - * + * * @param type $params * @param type $selects * @param type $order @@ -284,10 +284,10 @@ public function login($username,$password){ $path = Rest::LOGIN_PATH; $data = array('username'=>$username,'password'=>$password); - + return $this->loginRequest($path, $data); } - + public function logout($username) { $path = Rest::LOGOUT_PATH; $data = array('username' => $username); @@ -413,8 +413,15 @@ public function get($path,$data=array(),$selects=null,$order=null,$range=null,$d if($range) $headers[]=$range; $query = http_build_query($data); - if($query) - $path = "$path?$query"; + if($query) { + // if the path already has a question mark means that we should use an ampersand + if (strpos($path, "?") === false) { + $path = "$path?$query"; + } + else { + $path = "$path&$query"; + } + } return $this->request($path,'GET',null,implode("\n", $headers)); } @@ -455,7 +462,7 @@ protected function isProductionEnvironment() } /** - * + * * @param type $path * @param type $method * @param type $postData @@ -550,8 +557,8 @@ function processPostData($postData) return $postData; } - - function send_request($http_method, $url, $auth_header=null, $postData=null, $headers=null) { + + function send_request($http_method, $url, $auth_header=null, $postData=null, $headers=null) { $version = Configuration::getVersion(); $curl = curl_init($url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); @@ -647,7 +654,7 @@ function send_request($http_method, $url, $auth_header=null, $postData=null, $he /** - * + * * @param type $path * @param type $method * @param type $postData @@ -669,24 +676,24 @@ protected function request($path,$method,$postData=array(),$headers=null){ throw new LoginSessionExpiredException(); } // Perform OAuth2 request because logged in - + // Get Access Tokens from session $accessToken = $_SESSION[Rest::SM_LOGIN_ACCESS_TOKEN]; $macKey = $_SESSION[Rest::SM_LOGIN_MAC_KEY]; - + // Initialize OAuth2Signer $signer = new OAuth2Signer($accessToken, $macKey); - + // Url with port $urlWithPort = $this->_isSecure ? $this->_apiUrl . ':443' : $this->_apiUrl; - + // Get authorization string to include in request $authorizationString = $signer->generateMAC($method, $urlWithPort, $path); $this->log->debug("Authorization string: $authorizationString"); - + // Send request $response = $this->send_request(strtoupper($method), $endpoint, $authorizationString, $postData, $headers); - + } else { // OAuth 1 request // Setup OAuth request - Use NULL for OAuthToken parameter $request = OAuthRequest::from_consumer_and_token($this->_oauthConsumer, NULL, $method, $endpoint, $params); @@ -732,7 +739,7 @@ protected function deleteObjectPath($objectClass,$pk,$objectId) { * @param null $objectId * @return string */ - protected function + protected function userPath($username=null){ $pieces = array(Rest::USER_PATH); if($username){ diff --git a/src/Stackmob/User.php b/src/Stackmob/User.php index 0136c1a..bd500ed 100644 --- a/src/Stackmob/User.php +++ b/src/Stackmob/User.php @@ -48,7 +48,7 @@ public static function requestPasswordReset($email){ /** * https://developer.stackmob.com/sdks/rest/api#a-post_-_create_object - * + * * @param $username * @param $password * @param array $attributes @@ -61,8 +61,8 @@ public static function signUpUser($username, $password, $attributes=array()){ $user = null; $created = Object::$_restClient->createUser($username,$password,$attributes); - - + + if(Object::$_restClient->statusCode() == 201){ $user = new User((array)$created); @@ -126,12 +126,12 @@ public function isCurrent(){ /** * Logs in a \Stackmob\User, retrieves that user, * and puts in session. - * + * * @param $username * @param $password * @return boolean * @throws \Stackmob\StackmobException - * + * */ public function logIn($username = null, $password = null){ $this->log->debug("Logging in...."); @@ -160,12 +160,12 @@ public function logIn($username = null, $password = null){ $ret = true; } } - + return $ret; } /** - * + * * @return boolean * @throws \Stackmob\StackmobException */ @@ -179,8 +179,8 @@ public function logout() { } return $ret; } - - + + /** * Calls set("email", $email) * @param $email From df97bfe1d83a5ddd78f83a6b2912179f989e663e Mon Sep 17 00:00:00 2001 From: Federico Freire Date: Tue, 12 Nov 2013 13:13:36 -0300 Subject: [PATCH 28/29] Empty check added to query. --- src/Stackmob/Query.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/Stackmob/Query.php b/src/Stackmob/Query.php index ac45f6d..6e9a62b 100644 --- a/src/Stackmob/Query.php +++ b/src/Stackmob/Query.php @@ -97,6 +97,26 @@ public function isNull($key) { $this->setWhereKeyHashValue($key, 'null', 'true'); } + /** + * https://developer.stackmob.com/rest-api/api-docs#a-querying_for_empty_values + * + * @param type $key + */ + public function isEmpty($key) + { + $this->setWhereKeyHashValue($key, 'empty', 'true'); + } + + /** + * https://developer.stackmob.com/rest-api/api-docs#a-querying_for_empty_values + * + * @param type $key + */ + public function notEmpty($key) + { + $this->setWhereKeyHashValue($key, 'empty', 'false'); + } + /** * https://developer.stackmob.com/sdks/rest/api#a-querying_for_multiple_values * https://developer.stackmob.com/sdks/rest/api#a-querying_arrays From d1293338e1e7d5fe214b0f01de370deb8de358b7 Mon Sep 17 00:00:00 2001 From: Federico Freire Date: Wed, 22 Jan 2014 14:30:41 -0300 Subject: [PATCH 29/29] Order by functionality fixed for Query. --- src/Stackmob/Query.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Stackmob/Query.php b/src/Stackmob/Query.php index 6e9a62b..fa7af22 100644 --- a/src/Stackmob/Query.php +++ b/src/Stackmob/Query.php @@ -18,7 +18,7 @@ class Query extends Object { protected $_pk = null; protected $_where = array(); protected $_select = array(); - protected $_orderby = array(); + protected $_orderBy = array('asc' => array(), 'desc' => array()); protected $_depth = null; protected $_rest = null; protected $_range = null; @@ -152,7 +152,7 @@ public function select($values=array()) { * @param type $values */ public function asc($values=array()) { - $this->_orderby['asc'] = $values; + $this->_orderBy['asc'] = $values; } /** @@ -161,7 +161,7 @@ public function asc($values=array()) { * @param type $values */ public function desc($values=array()) { - $this->_orderby['desc'] = $values; + $this->_orderBy['desc'] = $values; } /**