├── .gitignore ├── .scrutinizer.yml ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── composer.json ├── phpunit.xml ├── src ├── Client.php ├── Exception.php ├── GetSetTrait.php ├── RateLimit.php └── Resources │ ├── Drivers.php │ ├── Estimates.php │ ├── Products.php │ ├── Promotions.php │ ├── Reminders.php │ ├── Requests.php │ └── Riders.php └── tests └── src └── UberTest.php /.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /vendor 3 | composer.phar 4 | composer.lock 5 | .DS_Store 6 | -------------------------------------------------------------------------------- /.scrutinizer.yml: -------------------------------------------------------------------------------- 1 | filter: 2 | excluded_paths: [tests/*] 3 | checks: 4 | php: 5 | code_rating: true 6 | remove_extra_empty_lines: true 7 | remove_php_closing_tag: true 8 | remove_trailing_whitespace: true 9 | fix_use_statements: 10 | remove_unused: true 11 | preserve_multiple: false 12 | preserve_blanklines: true 13 | order_alphabetically: true 14 | fix_php_opening_tag: true 15 | fix_linefeed: true 16 | fix_line_ending: true 17 | fix_identation_4spaces: true 18 | fix_doc_comments: true 19 | tools: 20 | external_code_coverage: 21 | timeout: 600 22 | runs: 2 23 | php_analyzer: true 24 | php_code_coverage: false 25 | php_code_sniffer: 26 | config: 27 | standard: PSR2 28 | filter: 29 | paths: ['src'] 30 | php_loc: 31 | enabled: true 32 | excluded_dirs: [vendor, tests] 33 | php_cpd: 34 | enabled: true 35 | excluded_dirs: [vendor, tests] 36 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | matrix: 4 | include: 5 | - php: 5.6 6 | - php: 7.0 7 | - php: 7.1 8 | - php: nightly 9 | - php: hhvm-3.6 10 | sudo: required 11 | dist: trusty 12 | group: edge 13 | - php: hhvm-3.9 14 | sudo: required 15 | dist: trusty 16 | group: edge 17 | - php: hhvm-3.12 18 | sudo: required 19 | dist: trusty 20 | group: edge 21 | - php: hhvm-3.15 22 | sudo: required 23 | dist: trusty 24 | group: edge 25 | - php: hhvm-nightly 26 | sudo: required 27 | dist: trusty 28 | group: edge 29 | fast_finish: true 30 | allow_failures: 31 | - php: nightly 32 | - php: hhvm-nightly 33 | 34 | before_script: 35 | - travis_retry composer self-update 36 | - travis_retry composer install --no-interaction --prefer-source --dev 37 | - travis_retry phpenv rehash 38 | 39 | script: 40 | - ./vendor/bin/phpcs --standard=psr2 src/ 41 | - ./vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover 42 | 43 | after_script: 44 | - if [ "$TRAVIS_PHP_VERSION" != "hhvm" ] && [ "$TRAVIS_PHP_VERSION" != "7.0" ]; then wget https://scrutinizer-ci.com/ocular.phar; fi 45 | - if [ "$TRAVIS_PHP_VERSION" != "hhvm" ] && [ "$TRAVIS_PHP_VERSION" != "7.0" ]; then php ocular.phar code-coverage:upload --format=php-clover coverage.clover; fi 46 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All Notable changes to `uber-php` will be documented in this file 3 | 4 | ## 1.6.0 - 2017-08-23 5 | 6 | ### Added 7 | - Support for driver endpoints 8 | 9 | ### Deprecated 10 | - Nothing 11 | 12 | ### Fixed 13 | - Nothing 14 | 15 | ### Removed 16 | - Nothing 17 | 18 | ### Security 19 | - Nothing 20 | 21 | ## 1.5.1 - 2017-08-03 22 | 23 | ### Added 24 | - Nothing 25 | 26 | ### Deprecated 27 | - Nothing 28 | 29 | ### Fixed 30 | - Updated incorrect verb used for updating existing entities. 31 | 32 | ### Removed 33 | - Nothing 34 | 35 | ### Security 36 | - Nothing 37 | 38 | ## 1.5.0 - 2016-11-21 39 | 40 | ### Added 41 | - Update rate limit parser to fail gracefully when no headers returned, as is expected in Uber API v1.2 42 | - Update default api version to v1.2 43 | - Add profile patch support 44 | - Add payment methods list support 45 | - Add place detail support 46 | - Add update place support 47 | - Add current ride request detail support 48 | - Add update current ride request support 49 | - Update sandbox method names to include intent 50 | - Add update specific request support 51 | - Add create reminder support 52 | - Add fetch reminder support 53 | - Add update reminder support 54 | - Add cancel reminder support 55 | - Add raised exception when invoking sandbox methods on non-sandbox client 56 | 57 | ### Deprecated 58 | - Removed `setProduct` method, replaced with `setSandboxProduct` 59 | 60 | ### Fixed 61 | - Nothing 62 | 63 | ### Removed 64 | - Nothing 65 | 66 | ### Security 67 | - Nothing 68 | 69 | ## 1.4.0 - 2015-07-08 70 | 71 | ### Added 72 | - Ride estimate API support 73 | - Ride receipt API support 74 | 75 | ### Deprecated 76 | - Nothing 77 | 78 | ### Fixed 79 | - Nothing 80 | 81 | ### Removed 82 | - Nothing 83 | 84 | ### Security 85 | - Nothing 86 | 87 | ## 1.3.1 - 2015-07-06 88 | 89 | ### Added 90 | - Corrected namespace for Guzzle 6 upgrade 91 | 92 | ### Deprecated 93 | - Nothing 94 | 95 | ### Fixed 96 | - Nothing 97 | 98 | ### Removed 99 | - Nothing 100 | 101 | ### Security 102 | - Nothing 103 | 104 | ## 1.3.0 - 2015-07-03 105 | 106 | ### Added 107 | - Upgraded Guzzle package to version 6 108 | - Bumped minimum PHP version from 5.4 to 5.5 109 | 110 | ### Deprecated 111 | - Nothing 112 | 113 | ### Fixed 114 | - Nothing 115 | 116 | ### Removed 117 | - Nothing 118 | 119 | ### Security 120 | - Nothing 121 | 122 | ## 1.2.0 - 2015-05-28 123 | 124 | ### Added 125 | - Added support for Sandbox PUT methods 126 | 127 | ### Deprecated 128 | - Nothing 129 | 130 | ### Fixed 131 | - Nothing 132 | 133 | ### Removed 134 | - Nothing 135 | 136 | ### Security 137 | - Nothing 138 | 139 | ## 1.1.0 - 2015-05-21 140 | 141 | ### Added 142 | - Improved handling of HTTP Errors from Uber API 143 | - Added ability to get HTTP Error response body from exception; helpful in "surge confirmation" flow. 144 | 145 | ### Deprecated 146 | - Nothing 147 | 148 | ### Fixed 149 | - Nothing 150 | 151 | ### Removed 152 | - Nothing 153 | 154 | ### Security 155 | - Nothing 156 | 157 | ## 1.0.0 - 2015-03-24 158 | 159 | ### Added 160 | - Uber API v1 and v1.1 Support 161 | - Toggle Sandbox mode 162 | - Check status of rate limiting 163 | 164 | ### Deprecated 165 | - Nothing 166 | 167 | ### Fixed 168 | - Nothing 169 | 170 | ### Removed 171 | - Nothing 172 | 173 | ### Security 174 | - Nothing 175 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions are **welcome** and will be fully **credited**. 4 | 5 | We accept contributions via Pull Requests on [Github](https://github.com/stevenmaguire/uber-php). 6 | 7 | 8 | ## Pull Requests 9 | 10 | - **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - The easiest way to apply the conventions is to install [PHP Code Sniffer](http://pear.php.net/package/PHP_CodeSniffer). 11 | 12 | - **Add tests!** - Your patch won't be accepted if it doesn't have tests. 13 | 14 | - **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date. 15 | 16 | - **Consider our release cycle** - We try to follow [SemVer v2.0.0](http://semver.org/). Randomly breaking public APIs is not an option. 17 | 18 | - **Create feature branches** - Don't ask us to pull from your master branch. 19 | 20 | - **One pull request per feature** - If you want to do more than one thing, send multiple pull requests. 21 | 22 | - **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please squash them before submitting. 23 | 24 | 25 | ## Running Tests 26 | 27 | ``` bash 28 | $ ./vendor/bin/phpunit 29 | ``` 30 | 31 | 32 | ## Running PHP Code Sniffer 33 | 34 | ``` bash 35 | $ ./vendor/bin/phpcs src --standard=psr2 -sp 36 | ``` 37 | 38 | 39 | **Happy coding**! 40 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Steven Maguire 4 | 5 | > Permission is hereby granted, free of charge, to any person obtaining a copy 6 | > of this software and associated documentation files (the "Software"), to deal 7 | > in the Software without restriction, including without limitation the rights 8 | > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | > copies of the Software, and to permit persons to whom the Software is 10 | > furnished to do so, subject to the following conditions: 11 | > 12 | > The above copyright notice and this permission notice shall be included in 13 | > all copies or substantial portions of the Software. 14 | > 15 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | > THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Uber PHP Client 2 | 3 | [![Latest Version](https://img.shields.io/github/release/stevenmaguire/uber-php.svg?style=flat-square)](https://github.com/stevenmaguire/uber-php/releases) 4 | [![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md) 5 | [![Build Status](https://img.shields.io/travis/stevenmaguire/uber-php/master.svg?style=flat-square&1)](https://travis-ci.org/stevenmaguire/uber-php) 6 | [![Coverage Status](https://img.shields.io/scrutinizer/coverage/g/stevenmaguire/uber-php.svg?style=flat-square)](https://scrutinizer-ci.com/g/stevenmaguire/uber-php/code-structure) 7 | [![Quality Score](https://img.shields.io/scrutinizer/g/stevenmaguire/uber-php.svg?style=flat-square)](https://scrutinizer-ci.com/g/stevenmaguire/uber-php) 8 | [![Total Downloads](https://img.shields.io/packagist/dt/stevenmaguire/uber-php.svg?style=flat-square)](https://packagist.org/packages/stevenmaguire/uber-php) 9 | 10 | A PHP client for authenticating with Uber using OAuth 2.0 and consuming the API. 11 | 12 | *This package is intended to be used for communicating with the Uber API after you've secured an access token from your users. To authenticate users and retrieve access tokens, use [stevenmaguire/oauth2-uber](https://github.com/stevenmaguire/oauth2-uber).* 13 | 14 | ## Install 15 | 16 | Via Composer 17 | 18 | ``` bash 19 | $ composer require stevenmaguire/uber-php 20 | ``` 21 | 22 | > Note that the required version of PHP is 5.5. If you want use library with PHP 5.4 you should use 1.2.0 version. 23 | 24 | ## Usage 25 | 26 | ### Create client 27 | 28 | ```php 29 | $client = new Stevenmaguire\Uber\Client(array( 30 | 'access_token' => 'YOUR ACCESS TOKEN', 31 | 'server_token' => 'YOUR SERVER TOKEN', 32 | 'use_sandbox' => true, // optional, default false 33 | 'version' => 'v1.2', // optional, default 'v1.2' 34 | 'locale' => 'en_US', // optional, default 'en_US' 35 | )); 36 | ``` 37 | *Please review the [Sandbox](https://developer.uber.com/docs/riders/guides/sandbox) documentation on how to develop and test against these endpoints without making real-world Requests and being charged.* 38 | 39 | ### Get Products 40 | 41 | #### By location: 42 | 43 | ```php 44 | $products = $client->getProducts(array( 45 | 'latitude' => '41.85582993', 46 | 'longitude' => '-87.62730337' 47 | )); 48 | ``` 49 | [https://developer.uber.com/docs/riders/references/api/v1.2/products-get](https://developer.uber.com/docs/riders/references/api/v1.2/products-get) 50 | 51 | #### By Id: 52 | 53 | ```php 54 | $product = $client->getProduct($productId); 55 | ``` 56 | 57 | [https://developer.uber.com/docs/riders/references/api/v1.2/products-product_id-get](https://developer.uber.com/docs/riders/references/api/v1.2/products-product_id-get) 58 | 59 | ### Get Price Estimates 60 | 61 | ```php 62 | $estimates = $client->getPriceEstimates(array( 63 | 'start_latitude' => '41.85582993', 64 | 'start_longitude' => '-87.62730337', 65 | 'end_latitude' => '41.87499492', 66 | 'end_longitude' => '-87.67126465' 67 | )); 68 | ``` 69 | 70 | [https://developer.uber.com/docs/riders/references/api/v1.2/estimates-price-get](https://developer.uber.com/docs/riders/references/api/v1.2/estimates-price-get) 71 | 72 | ### Get Time Estimates 73 | 74 | ```php 75 | $estimates = $client->getTimeEstimates(array( 76 | 'start_latitude' => '41.85582993', 77 | 'start_longitude' => '-87.62730337' 78 | )); 79 | ``` 80 | 81 | [https://developer.uber.com/docs/riders/references/api/v1.2/estimates-time-get](https://developer.uber.com/docs/riders/references/api/v1.2/estimates-time-get) 82 | 83 | ### Get Promotions 84 | 85 | ```php 86 | $promotions = $client->getPromotions(array( 87 | 'start_latitude' => '41.85582993', 88 | 'start_longitude' => '-87.62730337', 89 | 'end_latitude' => '41.87499492', 90 | 'end_longitude' => '-87.67126465' 91 | )); 92 | ``` 93 | 94 | [https://developer.uber.com/docs/riders/ride-promotions/introduction](https://developer.uber.com/docs/riders/ride-promotions/introduction) 95 | 96 | ### Get User Activity 97 | 98 | This feature is only available since version `1.1`. 99 | 100 | ```php 101 | $client->setVersion('v1.2'); // or v1.1 102 | $history = $client->getHistory(array( 103 | 'limit' => 50, // optional 104 | 'offset' => 0 // optional 105 | )); 106 | ``` 107 | 108 | [https://developer.uber.com/docs/riders/references/api/v1.2/history-get](https://developer.uber.com/docs/riders/references/api/v1.2/history-get) 109 | 110 | ### Get User Profile 111 | 112 | ```php 113 | $profile = $client->getProfile(); 114 | ``` 115 | 116 | [https://developer.uber.com/docs/riders/references/api/v1.2/me-get](https://developer.uber.com/docs/riders/references/api/v1.2/me-get) 117 | 118 | ### Update User Profile 119 | 120 | ```php 121 | $attributes = array('applied_promotion_codes' => 'PROMO_CODE'); 122 | $profileResponse = $client->setProfile($attributes); 123 | ``` 124 | 125 | [https://developer.uber.com/docs/riders/references/api/v1.2/me-patch](https://developer.uber.com/docs/riders/references/api/v1.2/me-patch) 126 | 127 | ### Get Payment Methods 128 | 129 | ```php 130 | $paymentMethods = $client->getPaymentMethods(); 131 | ``` 132 | 133 | [https://developer.uber.com/docs/riders/references/api/v1.2/payment-methods-get](https://developer.uber.com/docs/riders/references/api/v1.2/payment-methods-get) 134 | 135 | ### Get Place 136 | 137 | ```php 138 | $placeId = 'home'; 139 | $place = $client->getPlace($placeId); 140 | ``` 141 | 142 | [https://developer.uber.com/docs/riders/references/api/v1.2/places-place_id-get](https://developer.uber.com/docs/riders/references/api/v1.2/places-place_id-get) 143 | 144 | ### Update a Place 145 | 146 | ```php 147 | $placeId = 'home'; 148 | $attributes = array('address' => '685 Market St, San Francisco, CA 94103, USA'); 149 | $place = $client->setPlace($placeId, $attributes); 150 | ``` 151 | 152 | [https://developer.uber.com/docs/riders/references/api/v1.2/places-place_id-put](https://developer.uber.com/docs/riders/references/api/v1.2/places-place_id-put) 153 | 154 | ### Request A Ride 155 | 156 | ```php 157 | $request = $client->requestRide(array( 158 | 'start_latitude' => '41.85582993', 159 | 'start_longitude' => '-87.62730337', 160 | 'end_latitude' => '41.87499492', 161 | 'end_longitude' => '-87.67126465', 162 | 'product_id' => '4bfc6c57-98c0-424f-a72e-c1e2a1d49939', // Optional 163 | 'surge_confirmation_id' => 'e100a670', // Optional 164 | 'payment_method_id' => 'a1111c8c-c720-46c3-8534-2fcd' // Optional 165 | )); 166 | ``` 167 | 168 | #### Upfront Fares 169 | 170 | Upfront fares means the total fare is known before the ride is taken. 171 | 172 | - An end location is required 173 | - There is no surge confirmation flow 174 | - The user should specify a fare_id to confirm consent to the upfront fare 175 | - The user should specify the number of seats that are required for shared products (like UberPOOL) 176 | 177 | 1. In the products endpoint `GET /products`, products will have the `upfront_fare_enabled` field set to `true`. 178 | 2. Use the ride request estimate endpoint `POST /requests/estimate` with the `product_id` to get a `fare_id`. The `fare_id` can be used to lock down an upfront fare and arrival time for a trip. The `fare_id` expires after two minutes. If the `fare_id` is expired or not valid, we return a 422 error. 179 | 3. Request the ride using the ride request endpoint `POST /requests` with the `fare_id` returned in the previous step. 180 | 181 | [https://developer.uber.com/docs/riders/ride-requests/tutorials/api/best-practices#upfront-fares](https://developer.uber.com/docs/riders/ride-requests/tutorials/api/best-practices#upfront-fares) 182 | 183 | #### Surge Confirmation Flow 184 | 185 | If the ride request is using a product that has a surge multiplier, the API wrapper will throw an Exception and provide a response body that includes a surge confirmation ID. 186 | 187 | ```php 188 | try { 189 | $request = $client->requestRide(array( 190 | 'product_id' => '4bfc6c57-98c0-424f-a72e-c1e2a1d49939', 191 | 'start_latitude' => '41.85582993', 192 | 'start_longitude' => '-87.62730337', 193 | 'end_latitude' => '41.87499492', 194 | 'end_longitude' => '-87.67126465' 195 | )); 196 | } catch (Stevenmaguire\Uber\Exception $e) { 197 | $body = $e->getBody(); 198 | $surgeConfirmationId = $body['meta']['surge_confirmation']['surge_confirmation_id']; 199 | } 200 | ``` 201 | 202 | [https://developer.uber.com/docs/riders/ride-requests/tutorials/api/best-practices#handling-surge-pricing](https://developer.uber.com/docs/riders/ride-requests/tutorials/api/best-practices#handling-surge-pricing) 203 | 204 | ### Get Current Ride Details 205 | 206 | ```php 207 | $request = $client->getCurrentRequest(); 208 | ``` 209 | 210 | [https://developer.uber.com/docs/riders/references/api/v1.2/requests-current-get](https://developer.uber.com/docs/riders/references/api/v1.2/requests-current-get) 211 | 212 | ### Get Ride Details 213 | 214 | ```php 215 | $request = $client->getRequest($requestId); 216 | ``` 217 | 218 | [https://developer.uber.com/docs/riders/references/api/v1.2/requests-request_id-get](https://developer.uber.com/docs/riders/references/api/v1.2/requests-request_id-get) 219 | 220 | ### Update Current Ride Details 221 | 222 | ```php 223 | $requestDetails = array( 224 | 'end_address' => '685 Market St, San Francisco, CA 94103, USA', 225 | 'end_nickname' => 'da crib', 226 | 'end_place_id' => 'home', 227 | 'end_latitude' => '41.87499492', 228 | 'end_longitude' => '-87.67126465' 229 | ); 230 | 231 | $updateRequest = $client->setCurrentRequest($requestDetails); 232 | ``` 233 | 234 | [https://developer.uber.com/docs/riders/references/api/v1.2/requests-current-patch](https://developer.uber.com/docs/riders/references/api/v1.2/requests-current-patch) 235 | 236 | ### Update Ride Details 237 | 238 | ```php 239 | $requestId = '4bfc6c57-98c0-424f-a72e-c1e2a1d49939' 240 | $requestDetails = array( 241 | 'end_address' => '685 Market St, San Francisco, CA 94103, USA', 242 | 'end_nickname' => 'da crib', 243 | 'end_place_id' => 'home', 244 | 'end_latitude' => '41.87499492', 245 | 'end_longitude' => '-87.67126465' 246 | ); 247 | 248 | $updateRequest = $client->setRequest($requestId, $requestDetails); 249 | ``` 250 | 251 | [https://developer.uber.com/docs/riders/references/api/v1.2/requests-request_id-patch](https://developer.uber.com/docs/riders/references/api/v1.2/requests-request_id-patch) 252 | 253 | ### Get Ride Estimate 254 | 255 | ```php 256 | $requestEstimate = $client->getRequestEstimate(array( 257 | 'product_id' => '4bfc6c57-98c0-424f-a72e-c1e2a1d49939', 258 | 'start_latitude' => '41.85582993', 259 | 'start_longitude' => '-87.62730337', 260 | 'end_latitude' => '41.87499492', // optional 261 | 'end_longitude' => '-87.67126465', // optional 262 | )); 263 | ``` 264 | 265 | [https://developer.uber.com/docs/riders/references/api/v1.2/requests-estimate-post](https://developer.uber.com/docs/riders/references/api/v1.2/requests-estimate-post) 266 | 267 | ### Get Ride Map 268 | 269 | ```php 270 | $map = $client->getRequestMap($requestId); 271 | ``` 272 | 273 | [https://developer.uber.com/docs/riders/references/api/v1.2/requests-request_id-map-get](https://developer.uber.com/docs/riders/references/api/v1.2/requests-request_id-map-get) 274 | 275 | ### Get Ride Receipt 276 | 277 | ```php 278 | $receipt = $client->getRequestReceipt($requestId); 279 | ``` 280 | 281 | [https://developer.uber.com/docs/riders/references/api/v1.2/requests-request_id-receipt-get](https://developer.uber.com/docs/riders/references/api/v1.2/requests-request_id-receipt-get) 282 | 283 | ### Cancel Current Ride 284 | 285 | ```php 286 | $request = $client->cancelCurrentRequest(); 287 | ``` 288 | 289 | [https://developer.uber.com/docs/riders/references/api/v1.2/requests-current-delete](https://developer.uber.com/docs/riders/references/api/v1.2/requests-current-delete) 290 | 291 | ### Cancel Ride 292 | 293 | ```php 294 | $request = $client->cancelRequest($requestId); 295 | ``` 296 | 297 | [https://developer.uber.com/docs/riders/references/api/v1.2/requests-request_id-delete](https://developer.uber.com/docs/riders/references/api/v1.2/requests-request_id-delete) 298 | 299 | ### Create Reminder 300 | 301 | ```php 302 | $attributes = array( 303 | 'reminder_time' => '1429294463', 304 | 'phone_number' => '555-555-5555', 305 | 'event' => array( 306 | 'time' => '1429294463', 307 | 'name' => 'Frisbee with friends', 308 | 'location' => 'Dolores Park', 309 | 'latitude' => '37.759773', 310 | 'longitude' => '-122.427063', 311 | ), 312 | 'product_id' => 'a1111c8c-c720-46c3-8534-2fcdd730040d', 313 | 'trip_branding' => array( 314 | 'link_text' => 'View team roster', 315 | 'partner_deeplink' => 'partner://team/9383', 316 | ) 317 | ); 318 | $reminder = $client->createReminder($attributes); 319 | ``` 320 | 321 | [https://developer.uber.com/docs/riders/references/api/v1.2/reminders-post](https://developer.uber.com/docs/riders/references/api/v1.2/reminders-post) 322 | 323 | ### Get Reminder 324 | 325 | ```php 326 | $reminderId = '4bfc6c57-98c0-424f-a72e-c1e2a1d49939'; 327 | $reminder = $client->getReminder($reminderId); 328 | ``` 329 | 330 | [https://developer.uber.com/docs/riders/references/api/v1.2/reminders-reminder_id-get](https://developer.uber.com/docs/riders/references/api/v1.2/reminders-reminder_id-get) 331 | 332 | ### Update Reminder 333 | 334 | ```php 335 | $reminderId = '4bfc6c57-98c0-424f-a72e-c1e2a1d49939'; 336 | $attributes = array( 337 | 'reminder_time' => '1429294463', 338 | 'phone_number' => '555-555-5555', 339 | 'event' => array( 340 | 'time' => '1429294463', 341 | 'name' => 'Frisbee with friends', 342 | 'location' => 'Dolores Park', 343 | 'latitude' => '37.759773', 344 | 'longitude' => '-122.427063', 345 | ), 346 | 'product_id' => 'a1111c8c-c720-46c3-8534-2fcdd730040d', 347 | 'trip_branding' => array( 348 | 'link_text' => 'View team roster', 349 | 'partner_deeplink' => 'partner://team/9383', 350 | ) 351 | ); 352 | $reminder = $client->setReminder($reminderId, $attributes); 353 | ``` 354 | 355 | [https://developer.uber.com/docs/riders/references/api/v1.2/reminders-reminder_id-patch](https://developer.uber.com/docs/riders/references/api/v1.2/reminders-reminder_id-patch) 356 | 357 | ### Cancel Reminder 358 | 359 | ```php 360 | $reminderId = '4bfc6c57-98c0-424f-a72e-c1e2a1d49939'; 361 | $reminder = $client->cancelReminder($reminderId); 362 | ``` 363 | 364 | [https://developer.uber.com/docs/riders/references/api/v1.2/reminders-reminder_id-delete](https://developer.uber.com/docs/riders/references/api/v1.2/reminders-reminder_id-delete) 365 | 366 | ### Get Driver Profile 367 | 368 | ```php 369 | $profile = $client->getDriverProfile(); 370 | ``` 371 | 372 | [https://developer.uber.com/docs/drivers/references/api/v1/partners-me-get](https://developer.uber.com/docs/drivers/references/api/v1/partners-me-get) 373 | 374 | ### Get Driver Payments 375 | 376 | ```php 377 | $profile = $client->getDriverPayments(array( 378 | 'limit' => 50, // optional 379 | 'offset' => 0 // optional 380 | )); 381 | ``` 382 | 383 | [https://developer.uber.com/docs/drivers/references/api/v1/partners-payments-get](https://developer.uber.com/docs/drivers/references/api/v1/partners-payments-get) 384 | 385 | ### Get Driver Trips 386 | 387 | ```php 388 | $profile = $client->getDriverTrips(array( 389 | 'limit' => 50, // optional 390 | 'offset' => 0 // optional 391 | )); 392 | ``` 393 | 394 | [https://developer.uber.com/docs/drivers/references/api/v1/partners-trips-get](https://developer.uber.com/docs/drivers/references/api/v1/partners-trips-get) 395 | 396 | ### Rate Limiting 397 | 398 | > This feature is only supported for `v1` version of the API. 399 | 400 | Rate limiting is implemented on the basis of a specific client's secret token. By default, 1,000 requests per hour can be made per secret token. 401 | 402 | When consuming the service with this package, your rate limit status will be made available within the client. 403 | 404 | ```php 405 | $product = $client->getProduct($productId); 406 | 407 | $rateLimit = $client->getRateLimit(); 408 | 409 | $rateLimit->getLimit(); // Rate limit capacity per period 410 | $rateLimit->getRemaining(); // Requests remaining in current period 411 | $rateLimit->getReset(); // Timestamp in UTC time when the next period will begin 412 | ``` 413 | These values will update after each request. `getRateLimit` will return null after the client is created and before the first successful request. 414 | 415 | [https://developer.uber.com/v1/api-reference/#rate-limiting](https://developer.uber.com/v1/api-reference/#rate-limiting) 416 | 417 | ### Using the Sandbox 418 | 419 | Modify the status of an ongoing sandbox Request. 420 | 421 | > These methods will throw `Stevenmaguire\Uber\Exception` when invoked while the client is not in sandbox mode. The underlying API endpoints have no effect unless you are using the sandbox environment. 422 | 423 | ```php 424 | $request = $client->requestRide(array( 425 | 'product_id' => '4bfc6c57-98c0-424f-a72e-c1e2a1d49939', 426 | 'start_latitude' => '41.85582993', 427 | 'start_longitude' => '-87.62730337', 428 | 'end_latitude' => '41.87499492', 429 | 'end_longitude' => '-87.67126465' 430 | )); 431 | 432 | $updateRequest = $client->setSandboxRequest($request->request_id, array('status' => 'accepted')); 433 | ``` 434 | [https://developer.uber.com/v1/sandbox/#request](https://developer.uber.com/v1/sandbox/#request) 435 | 436 | Simulate the possible responses the Request endpoint will return when requesting a particular product, such as surge pricing, against the Sandbox. 437 | 438 | ```php 439 | $product = $client->getProduct($productId); 440 | 441 | $updateProduct = $client->setSandboxProduct($productId, array('surge_multiplier' => 2.2, 'drivers_available' => false)); 442 | ``` 443 | 444 | [https://developer.uber.com/v1/sandbox/#product-types](https://developer.uber.com/v1/sandbox/#product-types) 445 | 446 | ## Testing 447 | 448 | ``` bash 449 | $ ./vendor/bin/phpunit 450 | ``` 451 | 452 | ## Contributing 453 | 454 | Please see [CONTRIBUTING](CONTRIBUTING.md) for details. 455 | 456 | ## Credits 457 | 458 | - [Steven Maguire](https://github.com/stevenmaguire) 459 | - [All Contributors](https://github.com/stevenmaguire/uber-php/contributors) 460 | 461 | ## License 462 | 463 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 464 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "stevenmaguire/uber-php", 3 | "description": "A php client for consuming the Uber API", 4 | "version": "1.0.0", 5 | "homepage" : "http://github.com/stevenmaguire/uber-php", 6 | "authors" : [ 7 | { 8 | "name" : "Steven Maguire", 9 | "email" : "stevenmaguire@gmail.com", 10 | "homepage" : "http://stevenmaguire.com", 11 | "role" : "Developer" 12 | } 13 | ], 14 | "keywords": [ 15 | "api", 16 | "oauth2", 17 | "uber", 18 | "php" 19 | ], 20 | "license": "MIT", 21 | "require": { 22 | "php": ">=5.5.0", 23 | "guzzlehttp/guzzle": "~6.0" 24 | }, 25 | "require-dev": { 26 | "phpunit/phpunit": "~4.0", 27 | "mockery/mockery": "~0.9", 28 | "squizlabs/php_codesniffer": "~2.0" 29 | }, 30 | "autoload": { 31 | "psr-4": { 32 | "Stevenmaguire\\Uber\\": "src/" 33 | } 34 | }, 35 | "autoload-dev": { 36 | "psr-4": { 37 | "Stevenmaguire\\Uber\\Test\\": "tests/src/" 38 | } 39 | }, 40 | "suggest": { 41 | "stevenmaguire/oauth2-uber": "Making it simple to integrate your application with Uber using OAuth 2.0" 42 | }, 43 | "minimum-stability": "stable" 44 | } 45 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 20 | 22 | 23 | 24 | 25 | ./tests/ 26 | 27 | 28 | 29 | 30 | ./ 31 | 32 | ./vendor 33 | ./tests 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/Client.php: -------------------------------------------------------------------------------- 1 | parseConfiguration($configuration); 76 | $this->applyConfiguration($configuration); 77 | $this->httpClient = new HttpClient; 78 | } 79 | 80 | /** 81 | * Applies configuration to client. 82 | * 83 | * @param array $configuration 84 | * 85 | * @return void 86 | */ 87 | private function applyConfiguration($configuration = []) 88 | { 89 | array_walk($configuration, function ($value, $key) { 90 | $this->updateAttribute($key, $value); 91 | }); 92 | } 93 | 94 | /** 95 | * Gets authorization header value. 96 | * 97 | * @return string 98 | */ 99 | private function getAuthorizationHeader() 100 | { 101 | if ($this->access_token) { 102 | return 'Bearer '.$this->access_token; 103 | } 104 | 105 | return 'Token '.$this->server_token; 106 | } 107 | 108 | /** 109 | * Gets HttpClient config for verb and parameters. 110 | * 111 | * @param string $verb 112 | * @param array $parameters 113 | * 114 | * @return array 115 | */ 116 | private function getConfigForVerbAndParameters($verb, $parameters = []) 117 | { 118 | $config = [ 119 | 'headers' => $this->getHeaders() 120 | ]; 121 | 122 | if (!empty($parameters)) { 123 | if (strtolower($verb) == 'get') { 124 | $config['query'] = $parameters; 125 | } else { 126 | $config['json'] = $parameters; 127 | } 128 | } 129 | 130 | return $config; 131 | } 132 | 133 | /** 134 | * Gets headers for request. 135 | * 136 | * @return array 137 | */ 138 | public function getHeaders() 139 | { 140 | return [ 141 | 'Authorization' => trim($this->getAuthorizationHeader()), 142 | 'Accept-Language' => trim($this->locale), 143 | ]; 144 | } 145 | 146 | /** 147 | * Builds url from path. 148 | * 149 | * @param string $path 150 | * 151 | * @return string Url 152 | */ 153 | public function getUrlFromPath($path) 154 | { 155 | $path = ltrim($path, '/'); 156 | 157 | $host = 'https://'.($this->use_sandbox ? 'sandbox-' : '').'api.uber.com'; 158 | 159 | return $host.($this->version ? '/'.$this->version : '').'/'.$path; 160 | } 161 | 162 | /** 163 | * Handles http client exceptions. 164 | * 165 | * @param HttpClientException $e 166 | * 167 | * @return void 168 | * @throws Exception 169 | */ 170 | private function handleRequestException(HttpClientException $e) 171 | { 172 | if ($response = $e->getResponse()) { 173 | $exception = new Exception($response->getReasonPhrase(), $response->getStatusCode(), $e); 174 | $exception->setBody(json_decode($response->getBody())); 175 | 176 | throw $exception; 177 | } 178 | 179 | throw new Exception($e->getMessage(), 500, $e); 180 | } 181 | 182 | /** 183 | * Parses configuration using defaults. 184 | * 185 | * @param array $configuration 186 | * 187 | * @return array $configuration 188 | */ 189 | private function parseConfiguration($configuration = []) 190 | { 191 | $defaults = array( 192 | 'access_token' => null, 193 | 'server_token' => null, 194 | 'use_sandbox' => false, 195 | 'version' => 'v1.2', 196 | 'locale' => 'en_US', 197 | ); 198 | 199 | return array_merge($defaults, $configuration); 200 | } 201 | 202 | /** 203 | * Attempts to pull rate limit headers from response and add to client. 204 | * 205 | * @param Response $response 206 | * 207 | * @return void 208 | */ 209 | private function parseRateLimitFromResponse(Response $response) 210 | { 211 | $rateLimitHeaders = array_filter([ 212 | $response->getHeader('X-Rate-Limit-Limit'), 213 | $response->getHeader('X-Rate-Limit-Remaining'), 214 | $response->getHeader('X-Rate-Limit-Reset') 215 | ]); 216 | 217 | if (count($rateLimitHeaders) == 3) { 218 | $rateLimitClass = new ReflectionClass(RateLimit::class); 219 | $this->rate_limit = $rateLimitClass->newInstanceArgs($rateLimitHeaders); 220 | } 221 | } 222 | 223 | /** 224 | * Makes a request to the Uber API and returns the response. 225 | * 226 | * @param string $verb The Http verb to use 227 | * @param string $path The path of the APi after the domain 228 | * @param array $parameters Parameters 229 | * 230 | * @return stdClass The JSON response from the request 231 | * @throws Exception 232 | */ 233 | protected function request($verb, $path, $parameters = []) 234 | { 235 | $client = $this->httpClient; 236 | $url = $this->getUrlFromPath($path); 237 | $verb = strtolower($verb); 238 | $config = $this->getConfigForVerbAndParameters($verb, $parameters); 239 | 240 | try { 241 | $response = $client->$verb($url, $config); 242 | } catch (HttpClientException $e) { 243 | $this->handleRequestException($e); 244 | } 245 | 246 | $this->parseRateLimitFromResponse($response); 247 | 248 | return json_decode($response->getBody()); 249 | } 250 | 251 | /** 252 | * Sets Http Client. 253 | * 254 | * @param HttpClient $client 255 | * 256 | * @return Client 257 | */ 258 | public function setHttpClient(HttpClient $client) 259 | { 260 | $this->httpClient = $client; 261 | return $this; 262 | } 263 | 264 | /** 265 | * Throws exception when client is not configured sandbox use. Should only 266 | * be utilized when attempting to do work against ephemeral sandbox API 267 | * data. 268 | * 269 | * @return void 270 | * @throws Exception 271 | * 272 | * @see https://developer.uber.com/docs/riders/guides/sandbox 273 | */ 274 | private function enforceSandboxExpectation($message = null) 275 | { 276 | if (!$this->use_sandbox) { 277 | $message = $message ?: 'Attempted to invoke sandbox functionality '. 278 | 'with production client; this is not recommended'; 279 | throw new Exception($message); 280 | } 281 | } 282 | } 283 | -------------------------------------------------------------------------------- /src/Exception.php: -------------------------------------------------------------------------------- 1 | body; 22 | } 23 | 24 | /** 25 | * Set exception body 26 | * 27 | * @param string|array $body 28 | * 29 | * @return $this 30 | */ 31 | public function setBody($body = null) 32 | { 33 | $this->body = $body; 34 | 35 | return $this; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/GetSetTrait.php: -------------------------------------------------------------------------------- 1 | convertMethodToProperty($method); 17 | 18 | if ($this->isGetMethod($method)) { 19 | return $this->getAttribute($property); 20 | } elseif ($this->isSetMethod($method)) { 21 | return $this->updateAttribute($property, $parameters[0]); 22 | } // @codeCoverageIgnore 23 | 24 | throw new Exception($method . ' method not implemented'); 25 | } 26 | 27 | /** 28 | * Attempts to parse a method name and format its related property name. 29 | * 30 | * @param string $method 31 | * 32 | * @return string 33 | */ 34 | public function convertMethodToProperty($method) 35 | { 36 | $property = preg_replace("/[g|s]{1}et(.*)/", "$1", $method); 37 | 38 | return strtolower(preg_replace('/(.)(?=[A-Z])/', '$1'.'_', $property)); 39 | } 40 | 41 | /** 42 | * Fetches a specific attribute of the current object. 43 | * 44 | * @param string $attribute 45 | * 46 | * @return mixed|null 47 | */ 48 | private function getAttribute($attribute) 49 | { 50 | if (property_exists($this, $attribute)) { 51 | return $this->$attribute; 52 | } 53 | 54 | throw new Exception($attribute . ' attribute not defined'); 55 | } 56 | 57 | /** 58 | * Checks if given method name is a valid getter method. 59 | * 60 | * @param string $method 61 | * 62 | * @return boolean 63 | */ 64 | public function isGetMethod($method) 65 | { 66 | return preg_match("/^get[A-Za-z]+$/", $method); 67 | } 68 | 69 | /** 70 | * Checks if given method name is a valid setter method. 71 | * 72 | * @param string $method 73 | * 74 | * @return boolean 75 | */ 76 | public function isSetMethod($method) 77 | { 78 | return preg_match("/^set[A-Za-z]+$/", $method); 79 | } 80 | 81 | /** 82 | * Updates a specific attribute of the current object. 83 | * 84 | * @param string $attribute 85 | * @param string|boolean|integer $value 86 | * 87 | * @return object 88 | */ 89 | private function updateAttribute($attribute, $value) 90 | { 91 | if (property_exists($this, $attribute)) { 92 | $this->$attribute = $value; 93 | } 94 | 95 | return $this; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/RateLimit.php: -------------------------------------------------------------------------------- 1 | limit = $limit; 38 | $this->remaining = $remaining; 39 | $this->reset = $reset; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Resources/Drivers.php: -------------------------------------------------------------------------------- 1 | request('get', 'partners/me'); 18 | } 19 | 20 | /** 21 | * Makes a request to the Uber API and returns the response. 22 | * 23 | * @param string $verb The Http verb to use 24 | * @param string $path The path of the APi after the domain 25 | * @param array $parameters Parameters 26 | * 27 | * @return stdClass The JSON response from the request 28 | * @throws Exception 29 | */ 30 | abstract protected function request($verb, $path, $parameters = []); 31 | 32 | /** 33 | * Lists payments for the current driver. 34 | * 35 | * The Earnings endpoint returns an array of payments for the given driver. 36 | * Payments are available at this endpoint in near real-time. Some entries, 37 | * such as device_subscription will appear on a periodic basis when actually 38 | * billed to the partner. 39 | * 40 | * If a trip is cancelled (either by rider or driver) and there is no payment 41 | * made, the corresponding trip_id of that cancelled trip will not appear in 42 | * this endpoint. If the given driver works for a fleet manager, there will 43 | * be no payments associated and the response will always be an empty array. 44 | * Drivers working for fleet managers will receive payments from the fleet 45 | * manager and not from Uber. 46 | * 47 | * @param array $attributes 48 | * 49 | * @return stdClass The JSON response from the request 50 | * 51 | * @see https://developer.uber.com/docs/drivers/references/api/v1/partners-payments-get 52 | */ 53 | public function getDriverPayments($attributes = []) 54 | { 55 | return $this->request('get', '/partners/payments', $attributes); 56 | } 57 | 58 | /** 59 | * Lists trips for the current driver. 60 | * 61 | * The Trip History endpoint returns an array of trips for the authenticated 62 | * driver. 63 | * 64 | * @param array $attributes 65 | * 66 | * @return stdClass The JSON response from the request 67 | * 68 | * @see https://developer.uber.com/docs/drivers/references/api/v1/partners-trips-get 69 | */ 70 | public function getDriverTrips($attributes = []) 71 | { 72 | return $this->request('get', '/partners/trips', $attributes); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Resources/Estimates.php: -------------------------------------------------------------------------------- 1 | request('get', 'estimates/price', $attributes); 22 | } 23 | 24 | /** 25 | * Fetches a time estimate. 26 | * 27 | * The Time Estimates endpoint returns ETAs for all products offered at a 28 | * given location, with the responses expressed as integers in seconds. We 29 | * recommend that this endpoint be called every minute to provide the most 30 | * accurate, up-to-date ETAs. 31 | * 32 | * @param array $attributes Query attributes 33 | * 34 | * @return stdClass The JSON response from the request 35 | * 36 | * @see https://developer.uber.com/docs/riders/references/api/v1.2/estimates-time-get 37 | */ 38 | public function getTimeEstimates($attributes = []) 39 | { 40 | return $this->request('get', 'estimates/time', $attributes); 41 | } 42 | 43 | /** 44 | * Makes a request to the Uber API and returns the response. 45 | * 46 | * @param string $verb The Http verb to use 47 | * @param string $path The path of the APi after the domain 48 | * @param array $parameters Parameters 49 | * 50 | * @return stdClass The JSON response from the request 51 | * @throws Exception 52 | */ 53 | abstract protected function request($verb, $path, $parameters = []); 54 | } 55 | -------------------------------------------------------------------------------- /src/Resources/Products.php: -------------------------------------------------------------------------------- 1 | request('get', 'products/'.$productId); 17 | } 18 | 19 | /** 20 | * Lists available products. 21 | * 22 | * The Products endpoint returns information about the Uber products 23 | * offered at a given location. The response includes the display name and 24 | * other details about each product, and lists the products in the proper 25 | * display order. 26 | * 27 | * Some Products, such as experiments or promotions such as UberPOOL and 28 | * UberFRESH, will not be returned by this endpoint. 29 | * 30 | * @param array $attributes Query attributes 31 | * 32 | * @return stdClass The JSON response from the request 33 | * 34 | * @see https://developer.uber.com/docs/riders/references/api/v1.2/products-get 35 | */ 36 | public function getProducts($attributes = []) 37 | { 38 | return $this->request('get', 'products', $attributes); 39 | } 40 | 41 | /** 42 | * Makes a request to the Uber API and returns the response. 43 | * 44 | * @param string $verb The Http verb to use 45 | * @param string $path The path of the APi after the domain 46 | * @param array $parameters Parameters 47 | * 48 | * @return stdClass The JSON response from the request 49 | * @throws Exception 50 | */ 51 | abstract protected function request($verb, $path, $parameters = []); 52 | 53 | /** 54 | * Updates a specific product properties for sandbox responses. 55 | * 56 | * @param string $productId Product id 57 | * @param array $attributes Query attributes 58 | * 59 | * @return stdClass The JSON response from the request 60 | * @throws Exception 61 | * 62 | * @see https://developer.uber.com/docs/riders/guides/sandbox#product-types 63 | */ 64 | public function setSandboxProduct($productId, $attributes = []) 65 | { 66 | $this->enforceSandboxExpectation(); 67 | 68 | return $this->request('put', 'sandbox/products/'.$productId, $attributes); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/Resources/Promotions.php: -------------------------------------------------------------------------------- 1 | request('get', 'promotions', $attributes); 21 | } 22 | 23 | /** 24 | * Makes a request to the Uber API and returns the response. 25 | * 26 | * @param string $verb The Http verb to use 27 | * @param string $path The path of the APi after the domain 28 | * @param array $parameters Parameters 29 | * 30 | * @return stdClass The JSON response from the request 31 | * @throws Exception 32 | */ 33 | abstract protected function request($verb, $path, $parameters = []); 34 | } 35 | -------------------------------------------------------------------------------- /src/Resources/Reminders.php: -------------------------------------------------------------------------------- 1 | request('delete', 'reminders/'.$reminderId); 20 | } 21 | 22 | /** 23 | * Creates a new reminder. 24 | * 25 | * The Reminders endpoint allows developers to set a reminder for a future 26 | * trip. 27 | * 28 | * @param array $attributes Query attributes 29 | * 30 | * @return stdClass The JSON response from the request 31 | * 32 | * @see https://developer.uber.com/docs/riders/references/api/v1.2/reminders-post 33 | */ 34 | public function createReminder($attributes) 35 | { 36 | return $this->request('post', 'reminders', $attributes); 37 | } 38 | 39 | /** 40 | * Fetches a specific reminder. 41 | * 42 | * The Reminders endpoint allows you to get the status of an existing ride 43 | * reminder. 44 | * 45 | * @param string $reminderId Reminder id 46 | * 47 | * @return stdClass The JSON response from the request 48 | * 49 | * @see https://developer.uber.com/docs/riders/references/api/v1.2/reminders-reminder_id-get 50 | */ 51 | public function getReminder($reminderId) 52 | { 53 | return $this->request('get', 'reminders/'.$reminderId); 54 | } 55 | 56 | /** 57 | * Makes a request to the Uber API and returns the response. 58 | * 59 | * @param string $verb The Http verb to use 60 | * @param string $path The path of the APi after the domain 61 | * @param array $parameters Parameters 62 | * 63 | * @return stdClass The JSON response from the request 64 | * @throws Exception 65 | */ 66 | abstract protected function request($verb, $path, $parameters = []); 67 | 68 | /** 69 | * Updates a specific reminder. 70 | * 71 | * The Reminders endpoint allows you to update an existing reminder. 72 | * 73 | * @param string $reminderId Reminder id 74 | * @param array $attributes Query attributes 75 | * 76 | * @return stdClass The JSON response from the request 77 | * 78 | * @see https://developer.uber.com/docs/riders/references/api/v1.2/reminders-reminder_id-patch 79 | */ 80 | public function setReminder($reminderId, $attributes = []) 81 | { 82 | return $this->request('patch', 'reminders/'.$reminderId, $attributes); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/Resources/Requests.php: -------------------------------------------------------------------------------- 1 | cancelRequest('current'); 15 | } 16 | 17 | /** 18 | * Cancels a specific ride request. 19 | * 20 | * @param string $requestId Request id 21 | * 22 | * @return stdClass The JSON response from the request 23 | * 24 | * @see https://developer.uber.com/docs/riders/references/api/v1.2/requests-request_id-delete 25 | */ 26 | public function cancelRequest($requestId) 27 | { 28 | return $this->request('delete', 'requests/'.$requestId); 29 | } 30 | 31 | /** 32 | * Fetches the current ride request. 33 | * 34 | * The Ride Request endpoint allows retrieving real-time details for an 35 | * ongoing trip. 36 | * 37 | * This endpoint behaves similarly to the GET /requests/{request_id} 38 | * endpoint, except you do not need to provide a request_id. If there is 39 | * no trip in progress the endpoint will result in a 404 not found error. 40 | * This endpoint will only work for trips requested through your app unless 41 | * you have the all_trips scope. 42 | * 43 | * By default, only details about trips your app requested will be returned. 44 | * If your app has all_trips scope, however, trip details will be returned 45 | * for all trips irrespective of which application initiated them. 46 | * 47 | * See the Ride Request tutorial for a step-by-step guide to requesting 48 | * rides on behalf of an Uber user. Please review the Sandbox documentation 49 | * on how to develop and test against these endpoints without making 50 | * real-world Ride Requests and being charged. 51 | * 52 | * @return stdClass The JSON response from the request 53 | * 54 | * @see https://developer.uber.com/docs/riders/references/api/v1.2/requests-current-get 55 | */ 56 | public function getCurrentRequest() 57 | { 58 | return $this->getRequest('current'); 59 | } 60 | 61 | /** 62 | * Fetches a specific ride request. 63 | * 64 | * @param string $requestId Request id 65 | * 66 | * @return stdClass The JSON response from the request 67 | * 68 | * @see https://developer.uber.com/docs/riders/references/api/v1.2/requests-request_id-get 69 | */ 70 | public function getRequest($requestId) 71 | { 72 | return $this->request('get', 'requests/'.$requestId); 73 | } 74 | 75 | /** 76 | * Creates a ride request estimate. 77 | * 78 | * The Request Estimate endpoint allows a ride to be estimated given the 79 | * desired product, start, and end locations. If the end location is 80 | * not provided, only the pickup ETA and details of surge pricing 81 | * information are provided. If the pickup ETA is null, there are no cars 82 | * available, but an estimate may still be given to the user. 83 | * 84 | * @param array $attributes Query attributes 85 | * 86 | * @return stdClass The JSON response from the request 87 | * 88 | * @see https://developer.uber.com/docs/riders/references/api/v1.2/requests-estimate-post 89 | */ 90 | public function getRequestEstimate($attributes = []) 91 | { 92 | return $this->request('post', 'requests/estimate', $attributes); 93 | } 94 | 95 | /** 96 | * Fetches the map for a specific ride request. 97 | * 98 | * @param string $requestId Request id 99 | * 100 | * @return stdClass The JSON response from the request 101 | * 102 | * @see https://developer.uber.com/docs/riders/references/api/v1.2/requests-request_id-map-get 103 | */ 104 | public function getRequestMap($requestId) 105 | { 106 | return $this->request('get', 'requests/'.$requestId.'/map'); 107 | } 108 | 109 | /** 110 | * Fetches the receipt for a specific ride request. 111 | * 112 | * @param string $requestId Request id 113 | * 114 | * @return stdClass The JSON response from the request 115 | * 116 | * @see https://developer.uber.com/docs/riders/references/api/v1.2/requests-request_id-receipt-get 117 | */ 118 | public function getRequestReceipt($requestId) 119 | { 120 | return $this->request('get', 'requests/'.$requestId.'/receipt'); 121 | } 122 | 123 | /** 124 | * Makes a request to the Uber API and returns the response. 125 | * 126 | * @param string $verb The Http verb to use 127 | * @param string $path The path of the APi after the domain 128 | * @param array $parameters Parameters 129 | * 130 | * @return stdClass The JSON response from the request 131 | * @throws Exception 132 | */ 133 | abstract protected function request($verb, $path, $parameters = []); 134 | 135 | /** 136 | * Creates a new ride request. 137 | * 138 | * The Request endpoint allows a ride to be requested on behalf of an Uber 139 | * user given their desired product, start, and end locations. 140 | * 141 | * @param array $attributes Query attributes 142 | * 143 | * @return stdClass The JSON response from the request 144 | * 145 | * @see https://developer.uber.com/docs/riders/references/api/v1.2/requests-post 146 | */ 147 | public function requestRide($attributes = []) 148 | { 149 | return $this->request('post', 'requests', $attributes); 150 | } 151 | 152 | /** 153 | * Updates the current ride request. 154 | * 155 | * The Ride Request endpoint allows updating an ongoing request’s 156 | * destination. 157 | * 158 | * This endpoint behaves similarly to the PATCH /v1.2/requests/{request_id} 159 | * endpoint, except you do not need to provide a request_id. If there is no 160 | * trip in progress the endpoint will result in a 404 not found error. This 161 | * endpoint will only work for trips requested through your app unless you 162 | * have the all_trips scope. 163 | * 164 | * @param array $attributes Query attributes 165 | * 166 | * @return stdClass The JSON response from the request 167 | * 168 | * @see https://developer.uber.com/docs/riders/references/api/v1.2/requests-current-patch 169 | */ 170 | public function setCurrentRequest($attributes = []) 171 | { 172 | return $this->setRequest('current', $attributes); 173 | } 174 | 175 | /** 176 | * Updates a specific ride request. 177 | * 178 | * The Ride Request endpoint allows updating an ongoing request’s 179 | * destination using the Ride Request endpoint. 180 | * 181 | * @param string $requestId Request id 182 | * @param array $attributes Query attributes 183 | * 184 | * @return stdClass The JSON response from the request 185 | * 186 | * @see https://developer.uber.com/docs/riders/references/api/v1.2/requests-request_id-patch 187 | */ 188 | public function setRequest($requestId, $attributes = []) 189 | { 190 | return $this->request('patch', 'requests/'.$requestId, $attributes); 191 | } 192 | 193 | /** 194 | * Updates a specific ride request properties for sandbox responses. 195 | * 196 | * @param string $requestId Request id 197 | * @param array $attributes Query attributes 198 | * 199 | * @return stdClass The JSON response from the request 200 | * @throws Exception 201 | * 202 | * @see https://developer.uber.com/docs/riders/references/api/v1.2/requests-estimate-post 203 | */ 204 | public function setSandboxRequest($requestId, $attributes = []) 205 | { 206 | $this->enforceSandboxExpectation(); 207 | 208 | return $this->request('put', 'sandbox/requests/'.$requestId, $attributes); 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /src/Resources/Riders.php: -------------------------------------------------------------------------------- 1 | request('get', 'history', $attributes); 26 | } 27 | 28 | /** 29 | * Lists available payment methods for the current rider. 30 | * 31 | * The Payment Methods endpoint allows retrieving the list of the user’s 32 | * available payment methods. These can be leveraged in order to supply a 33 | * payment_method_id to the POST /requests endpoint. 34 | * 35 | * @return stdClass The JSON response from the request 36 | * 37 | * @see https://developer.uber.com/docs/riders/references/api/v1.2/payment-methods-get 38 | */ 39 | public function getPaymentMethods() 40 | { 41 | return $this->request('get', 'payment-methods'); 42 | } 43 | 44 | /** 45 | * Fetches a specific place. 46 | * 47 | * The Places endpoint allows retrieving the home and work addresses from 48 | * an Uber user's profile. 49 | * 50 | * Only home and work are acceptable. 51 | * 52 | * @param string $placeId Place id 53 | * 54 | * @return stdClass The JSON response from the request 55 | * 56 | * @see https://developer.uber.com/docs/riders/references/api/v1.2/places-place_id-get 57 | */ 58 | public function getPlace($placeId) 59 | { 60 | return $this->request('get', 'places/'.$placeId); 61 | } 62 | 63 | /** 64 | * Fetches the profile for the current rider. 65 | * 66 | * The User Profile endpoint returns information about the Uber user that 67 | * has authorized with the application. 68 | * 69 | * @return stdClass The JSON response from the request 70 | * 71 | * @see https://developer.uber.com/docs/riders/references/api/v1.2/me-get 72 | */ 73 | public function getProfile() 74 | { 75 | return $this->request('get', 'me'); 76 | } 77 | 78 | /** 79 | * Makes a request to the Uber API and returns the response. 80 | * 81 | * @param string $verb The Http verb to use 82 | * @param string $path The path of the APi after the domain 83 | * @param array $parameters Parameters 84 | * 85 | * @return stdClass The JSON response from the request 86 | * @throws Exception 87 | */ 88 | abstract protected function request($verb, $path, $parameters = []); 89 | 90 | /** 91 | * Updates a specific place. 92 | * 93 | * The Places endpoint allows updating the home and work addresses from an 94 | * Uber user's profile. 95 | * 96 | * Only home and work are acceptable. 97 | * 98 | * @param string $placeId Place id 99 | * @param array $attributes Query attributes 100 | * 101 | * @return stdClass 102 | * 103 | * @see https://developer.uber.com/docs/riders/references/api/v1.2/places-place_id-put 104 | */ 105 | public function setPlace($placeId, $attributes = []) 106 | { 107 | return $this->request('put', 'places/'.$placeId, $attributes); 108 | } 109 | 110 | /** 111 | * Updates the profile for the current rider. 112 | * 113 | * @param array $attributes 114 | * 115 | * @return stdClass 116 | * 117 | * @see https://developer.uber.com/docs/riders/references/api/v1.2/me-patch 118 | */ 119 | public function setProfile($attributes = []) 120 | { 121 | return $this->request('patch', 'me', $attributes); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /tests/src/UberTest.php: -------------------------------------------------------------------------------- 1 | client = new Uber([ 16 | 'access_token' => getenv('UBER_ACCESS_TOKEN'), 17 | 'server_token' => getenv('UBER_SERVER_TOKEN'), 18 | 'use_sandbox' => getenv('UBER_USE_SANDBOX'), 19 | 'version' => getenv('UBER_VERSION'), 20 | 'locale' => getenv('UBER_LOCALE'), 21 | ]); 22 | } 23 | 24 | public function testConfiguration() 25 | { 26 | $client = new Uber([ 27 | 'access_token' => getenv('UBER_ACCESS_TOKEN'), 28 | 'server_token' => getenv('UBER_SERVER_TOKEN'), 29 | 'use_sandbox' => getenv('UBER_USE_SANDBOX'), 30 | 'version' => getenv('UBER_VERSION'), 31 | 'locale' => getenv('UBER_LOCALE'), 32 | ]); 33 | 34 | $this->assertEquals($client->getAccessToken(), getenv('UBER_ACCESS_TOKEN')); 35 | $this->assertEquals($client->getServerToken(), getenv('UBER_SERVER_TOKEN')); 36 | $this->assertEquals($client->getUseSandbox(), getenv('UBER_USE_SANDBOX')); 37 | $this->assertEquals($client->getVersion(), getenv('UBER_VERSION')); 38 | $this->assertEquals($client->getLocale(), getenv('UBER_LOCALE')); 39 | } 40 | 41 | public function testConfigurationDefaults() 42 | { 43 | $client = new Uber(); 44 | 45 | $this->assertEquals(null, $client->getAccessToken()); 46 | $this->assertEquals(null, $client->getServerToken()); 47 | $this->assertEquals(false, $client->getUseSandbox()); 48 | $this->assertEquals('v1.2', $client->getVersion()); 49 | $this->assertEquals('en_US', $client->getLocale()); 50 | } 51 | 52 | /** 53 | * @expectedException Stevenmaguire\Uber\Exception 54 | */ 55 | public function testConfigurationWillNotAcceptNonPropertyConfig() 56 | { 57 | $client = new Uber([ 58 | 'non_existent_property' => 'test', 59 | ]); 60 | 61 | $client->getNonExistentProperty(); 62 | } 63 | 64 | public function testUrlIncludesVersion() 65 | { 66 | $version = uniqid(); 67 | $this->client->setVersion($version); 68 | 69 | $url = $this->client->getUrlFromPath('/'); 70 | 71 | $this->assertContains($version, $url); 72 | } 73 | 74 | public function testUrlOmitsVersionWhenNotProvided() 75 | { 76 | $this->client->setVersion(null); 77 | 78 | $url = $this->client->getUrlFromPath('/'); 79 | 80 | $this->assertStringEndsNotWith('//', $url); 81 | } 82 | 83 | public function testHeadersIncludeBearerWhenAccessTokenProvided() 84 | { 85 | $access_token = uniqid(); 86 | $this->client->setAccessToken($access_token); 87 | 88 | $headers = $this->client->getHeaders(); 89 | 90 | $this->assertTrue(in_array('Authorization', array_keys($headers))); 91 | $this->assertEquals('Bearer '.$access_token, $headers['Authorization']); 92 | } 93 | 94 | public function testHeadersIncludeTokenWhenAccessTokenNotProvided() 95 | { 96 | $server_token = uniqid(); 97 | $this->client->setServerToken($server_token)->setAccessToken(null); 98 | 99 | $headers = $this->client->getHeaders(); 100 | 101 | $this->assertTrue(in_array('Authorization', array_keys($headers))); 102 | $this->assertEquals('Token '.$server_token, $headers['Authorization']); 103 | } 104 | 105 | public function testHeadersIncludeEmptyTokenWhenAccessAndServerTokenNotProvided() 106 | { 107 | $this->client->setServerToken(null)->setAccessToken(null); 108 | 109 | $headers = $this->client->getHeaders(); 110 | 111 | $this->assertTrue(in_array('Authorization', array_keys($headers))); 112 | $this->assertEquals('Token', $headers['Authorization']); 113 | } 114 | 115 | public function testHeadersIncludeAcceptLanguageWhenLocaleProvided() 116 | { 117 | $locale = $this->client->getLocale(); 118 | 119 | $headers = $this->client->getHeaders(); 120 | 121 | $this->assertTrue(in_array('Accept-Language', array_keys($headers))); 122 | $this->assertEquals($locale, $headers['Accept-Language']); 123 | } 124 | 125 | public function testHeadersIncludeEmptyAcceptLanguageWhenLocaleNotProvided() 126 | { 127 | $headers = $this->client->setLocale(null)->getHeaders(); 128 | 129 | $this->assertTrue(in_array('Accept-Language', array_keys($headers))); 130 | $this->assertEmpty($headers['Accept-Language']); 131 | } 132 | 133 | public function testGetPaymentMethods() 134 | { 135 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 136 | $getResponse->shouldReceive('getBody')->times(1)->andReturn('{"payment_methods": [{"payment_method_id": "5f384f7d-8323-4207-a297-51c571234a8c","type": "baidu_wallet","description": "***53",},{"payment_method_id": "f33847de-8113-4587-c307-51c2d13a823c","type": "alipay","description": "ga***@uber.com",},{"payment_method_id": "f43847de-8113-4587-c307-51c2d13a823c","type": "visa","description": "***23"},{"payment_method_id": "517a6c29-3a2b-45cb-94a3-35d679909a71","type": "american_express","description": "***05"},{"payment_method_id": "f53847de-8113-4587-c307-51c2d13a823c","type": "business_account","description": "Late Night Ride"}],"last_used": "f53847de-8113-4587-c307-51c2d13a823c"}'); 137 | $getResponse->shouldReceive('getHeader')->times(3)->andReturn(null); 138 | 139 | $http_client = m::mock('GuzzleHttp\Client'); 140 | $http_client->shouldReceive('get') 141 | ->with($this->client->getUrlFromPath('/payment-methods'), ['headers' => $this->client->getHeaders()]) 142 | ->times(1)->andReturn($getResponse); 143 | 144 | $this->client->setHttpClient($http_client); 145 | 146 | $product = $this->client->getPaymentMethods(); 147 | } 148 | 149 | public function testGetPlace() 150 | { 151 | $place_id = 'mock_place_id'; 152 | 153 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 154 | $getResponse->shouldReceive('getBody')->times(1)->andReturn('{"address": "685 Market St, San Francisco, CA 94103, USA"'); 155 | $getResponse->shouldReceive('getHeader')->times(3)->andReturn(null); 156 | 157 | $http_client = m::mock('GuzzleHttp\Client'); 158 | $http_client->shouldReceive('get') 159 | ->with($this->client->getUrlFromPath('/places/'.$place_id), ['headers' => $this->client->getHeaders()]) 160 | ->times(1)->andReturn($getResponse); 161 | 162 | $this->client->setHttpClient($http_client); 163 | 164 | $product = $this->client->getPlace($place_id); 165 | } 166 | 167 | public function testGetProducts() 168 | { 169 | $params = [ 170 | 'latitude' => '41.85582993', 171 | 'longitude' => '-87.62730337' 172 | ]; 173 | 174 | $this->client->setAccessToken(null); 175 | 176 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 177 | $getResponse->shouldReceive('getBody')->times(1)->andReturn('{"products": [{"product_id": "327f7914-cd12-4f77-9e0c-b27bac580d03","description": "The original Uber","display_name": "UberBLACK","capacity": 4,"image": "http://..."},{"product_id": "955b92da-2b90-4f32-9586-f766cee43b99","description": "Room for everyone","display_name": "UberSUV","capacity": 6,"image": "http://..."},{"product_id": "622237e-c1e4-4523-b6e7-e1ac53f625ed","description": "Taxi without the hassle","display_name": "uberTAXI","capacity": 4,"image": "http://..."},{"product_id": "b5e74e96-5d27-4caf-83e9-54c030cd6ac5","description": "The low-cost Uber","display_name": "uberX","capacity": 4,"image": "http://..."}]}'); 178 | $getResponse->shouldReceive('getHeader')->times(3)->andReturnValues([1000, 955, strtotime("+1 day")]); 179 | 180 | $http_client = m::mock('GuzzleHttp\Client'); 181 | $http_client->shouldReceive('get') 182 | ->with($this->client->getUrlFromPath('/products'), ['headers' => $this->client->getHeaders(), 'query' => $params]) 183 | ->times(1)->andReturn($getResponse); 184 | 185 | $this->client->setHttpClient($http_client); 186 | 187 | $products = $this->client->getProducts($params); 188 | $this->assertNull($this->client->getAccessToken()); 189 | } 190 | 191 | public function testGetProduct() 192 | { 193 | $product_id = 'mock_product_id'; 194 | 195 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 196 | $getResponse->shouldReceive('getBody')->times(1)->andReturn('{"product_id": "'.$product_id.'","description": "The original Uber","display_name": "UberBLACK","capacity": 4,"image": "http://..."}'); 197 | $getResponse->shouldReceive('getHeader')->times(3)->andReturnValues([1000, 955, strtotime("+1 day")]); 198 | 199 | $http_client = m::mock('GuzzleHttp\Client'); 200 | $http_client->shouldReceive('get') 201 | ->with($this->client->getUrlFromPath('/products/'.$product_id), ['headers' => $this->client->getHeaders()]) 202 | ->times(1)->andReturn($getResponse); 203 | 204 | $this->client->setHttpClient($http_client); 205 | 206 | $product = $this->client->getProduct($product_id); 207 | } 208 | 209 | public function testGetPriceEstimates() 210 | { 211 | $params = [ 212 | 'start_latitude' => '41.85582993', 213 | 'start_longitude' => '-87.62730337', 214 | 'end_latitude' => '41.87499492', 215 | 'end_longitude' => '-87.67126465', 216 | ]; 217 | 218 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 219 | $getResponse->shouldReceive('getBody')->times(1)->andReturn('{"prices": [{"product_id": "08f17084-23fd-4103-aa3e-9b660223934b","currency_code": "USD","display_name": "UberBLACK","estimate": "$23-29","low_estimate": 23,"high_estimate": 29,"surge_multiplier": 1,"duration": 640,"distance": 5.34},{"product_id": "9af0174c-8939-4ef6-8e91-1a43a0e7c6f6","currency_code": "USD","display_name": "UberSUV","estimate": "$36-44","low_estimate": 36,"high_estimate": 44,"surge_multiplier": 1.25,"duration": 640,"distance": 5.34},{"product_id": "aca52cea-9701-4903-9f34-9a2395253acb","currency_code": null,"display_name": "uberTAXI","estimate": "Metered","low_estimate": null,"high_estimate": null,"surge_multiplier": 1,"duration": 640,"distance": 5.34},{"product_id": "a27a867a-35f4-4253-8d04-61ae80a40df5","currency_code": "USD","display_name": "uberX","estimate": "$15","low_estimate": 15,"high_estimate": 15,"surge_multiplier": 1,"duration": 640,"distance": 5.34}]}'); 220 | $getResponse->shouldReceive('getHeader')->times(3)->andReturnValues([1000, 955, strtotime("+1 day")]); 221 | 222 | $http_client = m::mock('GuzzleHttp\Client'); 223 | $http_client->shouldReceive('get') 224 | ->with($this->client->getUrlFromPath('/estimates/price'), ['headers' => $this->client->getHeaders(), 'query' => $params]) 225 | ->times(1)->andReturn($getResponse); 226 | 227 | $this->client->setHttpClient($http_client); 228 | 229 | $estimates = $this->client->getPriceEstimates($params); 230 | } 231 | 232 | public function testGetReminder() 233 | { 234 | $reminder_id = 'mock_reminder_id'; 235 | 236 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 237 | $getResponse->shouldReceive('getBody')->times(1)->andReturn('{"event": {"name": "Frisbee with friends","location": "Dolores Park","latitude": 37.759773,"longitude": -122.427063,"time": 1429294463},"product_id": "a1111c8c-c720-46c3-8534-2fcdd730040d","reminder_id": "def-456","reminder_time": 1429294463,"reminder_status": "pending","trip_branding": {"link_text": "View team roster","partner_deeplink": "partner://team/9383"}}'); 238 | $getResponse->shouldReceive('getHeader')->times(3)->andReturn(null); 239 | 240 | $http_client = m::mock('GuzzleHttp\Client'); 241 | $http_client->shouldReceive('get') 242 | ->with($this->client->getUrlFromPath('/reminders/'.$reminder_id), ['headers' => $this->client->getHeaders()]) 243 | ->times(1)->andReturn($getResponse); 244 | 245 | $this->client->setHttpClient($http_client); 246 | 247 | $reminder = $this->client->getReminder($reminder_id); 248 | } 249 | 250 | public function testGetTimeEstimates() 251 | { 252 | $params = [ 253 | 'start_latitude' => '41.85582993', 254 | 'start_longitude' => '-87.62730337', 255 | ]; 256 | 257 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 258 | $getResponse->shouldReceive('getBody')->times(1)->andReturn('{"times": [{"product_id": "5f41547d-805d-4207-a297-51c571cf2a8c","display_name": "UberBLACK","estimate": 410},{"product_id": "694558c9-b34b-4836-855d-821d68a4b944","display_name": "UberSUV","estimate": 535},{"product_id": "65af3521-a04f-4f80-8ce2-6d88fb6648bc","display_name": "uberTAXI","estimate": 294},{"product_id": "17b011d3-65be-421d-adf6-a5480a366453","display_name": "uberX","estimate": 288}]}'); 259 | $getResponse->shouldReceive('getHeader')->times(3)->andReturnValues([1000, 955, strtotime("+1 day")]); 260 | 261 | $http_client = m::mock('GuzzleHttp\Client'); 262 | $http_client->shouldReceive('get') 263 | ->with($this->client->getUrlFromPath('/estimates/time'), ['headers' => $this->client->getHeaders(), 'query' => $params]) 264 | ->times(1)->andReturn($getResponse); 265 | 266 | $this->client->setHttpClient($http_client); 267 | 268 | $estimates = $this->client->getTimeEstimates($params); 269 | } 270 | 271 | public function testGetPromotions() 272 | { 273 | $params = [ 274 | 'start_latitude' => '41.85582993', 275 | 'start_longitude' => '-87.62730337', 276 | 'end_latitude' => '41.87499492', 277 | 'end_longitude' => '-87.67126465', 278 | ]; 279 | 280 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 281 | $getResponse->shouldReceive('getBody')->times(1)->andReturn('{"display_text": "Free ride up to $30","localized_value": "$30","type": "trip_credit"}'); 282 | $getResponse->shouldReceive('getHeader')->times(3)->andReturnValues([1000, 955, strtotime("+1 day")]); 283 | 284 | $http_client = m::mock('GuzzleHttp\Client'); 285 | $http_client->shouldReceive('get') 286 | ->with($this->client->getUrlFromPath('/promotions'), ['headers' => $this->client->getHeaders(), 'query' => $params]) 287 | ->times(1)->andReturn($getResponse); 288 | 289 | $this->client->setHttpClient($http_client); 290 | 291 | $promotions = $this->client->getPromotions($params); 292 | } 293 | 294 | public function testGetHistory() 295 | { 296 | $params = [ 297 | 'limit' => 1, 298 | 'offset' => 1 299 | ]; 300 | 301 | $this->client->setVersion('v1.1'); 302 | 303 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 304 | $getResponse->shouldReceive('getBody')->times(1)->andReturn('{"offset": 0,"limit": 1,"count": 5,"history": [{"uuid": "7354db54-cc9b-4961-81f2-0094b8e2d215","request_time": 1401884467,"product_id": "edf5e5eb-6ae6-44af-bec6-5bdcf1e3ed2c","status": "completed","distance": 0.0279562,"start_time": 1401884646,"end_time": 1401884732}]}'); 305 | $getResponse->shouldReceive('getHeader')->times(3)->andReturnValues([1000, 955, strtotime("+1 day")]); 306 | 307 | $http_client = m::mock('GuzzleHttp\Client'); 308 | $http_client->shouldReceive('get') 309 | ->with($this->client->getUrlFromPath('/history'), ['headers' => $this->client->getHeaders(), 'query' => $params]) 310 | ->times(1)->andReturn($getResponse); 311 | 312 | $this->client->setHttpClient($http_client); 313 | 314 | $history = $this->client->getHistory($params); 315 | } 316 | 317 | public function testGetProfilewithRateLimitHeaders() 318 | { 319 | $rateLimitHeaders = [1000, 955, strtotime("+1 day")]; 320 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 321 | $getResponse->shouldReceive('getBody')->times(1)->andReturn('{"first_name": "Uber","last_name": "Developer","email": "developer@uber.com","picture": "https://...","promo_code": "teypo","uuid": "91d81273-45c2-4b57-8124-d0165f8240c0"}'); 322 | $getResponse->shouldReceive('getHeader')->times(3)->andReturnValues($rateLimitHeaders); 323 | 324 | $http_client = m::mock('GuzzleHttp\Client'); 325 | $http_client->shouldReceive('get') 326 | ->with($this->client->getUrlFromPath('/me'), ['headers' => $this->client->getHeaders()]) 327 | ->times(1)->andReturn($getResponse); 328 | 329 | $this->client->setHttpClient($http_client); 330 | 331 | $profile = $this->client->getProfile(); 332 | $rateLimit = $this->client->getRateLimit(); 333 | $this->assertEquals($rateLimit->getLimit(), $rateLimitHeaders[0]); 334 | $this->assertEquals($rateLimit->getRemaining(), $rateLimitHeaders[1]); 335 | $this->assertEquals($rateLimit->getReset(), $rateLimitHeaders[2]); 336 | } 337 | 338 | public function testGetProfilewithoutRateLimitHeaders() 339 | { 340 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 341 | $getResponse->shouldReceive('getBody')->times(1)->andReturn('{"first_name": "Uber","last_name": "Developer","email": "developer@uber.com","picture": "https://...","promo_code": "teypo","uuid": "91d81273-45c2-4b57-8124-d0165f8240c0"}'); 342 | $getResponse->shouldReceive('getHeader')->times(3)->andReturnValues([null, null, null]); 343 | 344 | $http_client = m::mock('GuzzleHttp\Client'); 345 | $http_client->shouldReceive('get') 346 | ->with($this->client->getUrlFromPath('/me'), ['headers' => $this->client->getHeaders()]) 347 | ->times(1)->andReturn($getResponse); 348 | 349 | $this->client->setHttpClient($http_client); 350 | 351 | $profile = $this->client->getProfile(); 352 | $rateLimit = $this->client->getRateLimit(); 353 | $this->assertNull($rateLimit); 354 | } 355 | 356 | public function testGetRequestEstimate() 357 | { 358 | $params = [ 359 | 'product_id' => '4bfc6c57-98c0-424f-a72e-c1e2a1d49939', 360 | 'start_latitude' => '41.85582993', 361 | 'start_longitude' => '-87.62730337', 362 | 'end_latitude' => '41.87499492', 363 | 'end_longitude' => '-87.67126465', 364 | ]; 365 | 366 | $postResponse = m::mock('GuzzleHttp\Psr7\Response'); 367 | $postResponse->shouldReceive('getBody')->times(1)->andReturn('{"price":{"surge_multiplier]": 1,"minimum": 15,"surge_confirmation_href": "","currency_code": "USD","surge_confirmation_id]": ""},"trip": {"pickup_estimate": 10}}'); 368 | $postResponse->shouldReceive('getHeader')->times(3)->andReturnValues([1000, 955, strtotime("+1 day")]); 369 | 370 | $http_client = m::mock('GuzzleHttp\Client'); 371 | $http_client->shouldReceive('post') 372 | ->with($this->client->getUrlFromPath('/requests/estimate'), ['headers' => $this->client->getHeaders(), 'json' => $params]) 373 | ->times(1)->andReturn($postResponse); 374 | 375 | $this->client->setHttpClient($http_client); 376 | 377 | $requestEstimate = $this->client->getRequestEstimate($params); 378 | } 379 | 380 | public function testGetDriverProfile() 381 | { 382 | $this->client->setVersion('v1.1'); 383 | 384 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 385 | $getResponse->shouldReceive('getBody')->times(1)->andReturn('{"driver_id": "8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","first_name": "Uber","last_name": "Tester","email": "uber.developer+tester@example.com","phone_number": "+15555550001","picture": "https://d1w2poirtb3as9.cloudfront.net/16ce502f4767f17b120e.png","promo_code": "ubert4544ue","rating": 5,"activation_status": "active"}'); 386 | $getResponse->shouldReceive('getHeader')->times(3)->andReturnValues([1000, 955, strtotime("+1 day")]); 387 | 388 | $http_client = m::mock('GuzzleHttp\Client'); 389 | $http_client->shouldReceive('get') 390 | ->with($this->client->getUrlFromPath('/partners/me'), ['headers' => $this->client->getHeaders()]) 391 | ->times(1)->andReturn($getResponse); 392 | 393 | $this->client->setHttpClient($http_client); 394 | 395 | $history = $this->client->getDriverProfile(); 396 | } 397 | 398 | public function testGetDriverPayments() 399 | { 400 | $params = [ 401 | 'limit' => 1, 402 | 'offset' => 1 403 | ]; 404 | 405 | $this->client->setVersion('v1.1'); 406 | 407 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 408 | $getResponse->shouldReceive('getBody')->times(1)->andReturn('{"count": 1200,"limit": 1,"payments": [{"payment_id": "5cb8304c-f3f0-4a46-b6e3-b55e020750d7","category": "fare","event_time": 1502842757,"trip_id": "5cb8304c-f3f0-4a46-b6e3-b55e020750d7","cash_collected": 0,"amount": 3.12,"driver_id": "8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","breakdown": {"other": 4.16,"toll": 1,"service_fee": -1.04},"rider_fees": {"split_fare": 0.50},"partner_id": "8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","currency_code": "USD"}],"offset": 0}'); 409 | $getResponse->shouldReceive('getHeader')->times(3)->andReturnValues([1000, 955, strtotime("+1 day")]); 410 | 411 | $http_client = m::mock('GuzzleHttp\Client'); 412 | $http_client->shouldReceive('get') 413 | ->with($this->client->getUrlFromPath('/partners/payments'), ['headers' => $this->client->getHeaders(), 'query' => $params]) 414 | ->times(1)->andReturn($getResponse); 415 | 416 | $this->client->setHttpClient($http_client); 417 | 418 | $history = $this->client->getDriverPayments($params); 419 | } 420 | 421 | public function testGetDriverTrips() 422 | { 423 | $params = [ 424 | 'limit' => 1, 425 | 'offset' => 1 426 | ]; 427 | 428 | $this->client->setVersion('v1.1'); 429 | 430 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 431 | $getResponse->shouldReceive('getBody')->times(1)->andReturn('{"count": 1200,"limit": 1,"trips": [{"fare": 6.2,"dropoff": {"timestamp": 1502844378},"vehicle_id": "0082b54a-6a5e-4f6b-b999-b0649f286381","distance": 0.37,"start_city": {"latitude": 38.3498,"display_name": "Charleston, WV","longitude": -81.6326},"status_changes": [{"status": "accepted","timestamp": 1502843899},{"status": "driver_arrived","timestamp": 1502843900},{"status": "trip_began","timestamp": 1502843903},{"status": "completed","timestamp": 1502844378}],"surge_multiplier": 1,"pickup": {"timestamp": 1502843903},"driver_id": "8LvWuRAq2511gmr8EMkovekFNa2848lyMaQevIto-aXmnK9oKNRtfTxYLgPq9OSt8EzAu5pDB7XiaQIrcp-zXgOA5EyK4h00U6D1o7aZpXIQah--U77Eh7LEBiksj2rahB==","status": "completed","duration": 475,"trip_id": "b5613b6a-fe74-4704-a637-50f8d51a8bb1","currency_code": "USD"}],"offset": 0}'); 432 | $getResponse->shouldReceive('getHeader')->times(3)->andReturnValues([1000, 955, strtotime("+1 day")]); 433 | 434 | $http_client = m::mock('GuzzleHttp\Client'); 435 | $http_client->shouldReceive('get') 436 | ->with($this->client->getUrlFromPath('/partners/trips'), ['headers' => $this->client->getHeaders(), 'query' => $params]) 437 | ->times(1)->andReturn($getResponse); 438 | 439 | $this->client->setHttpClient($http_client); 440 | 441 | $history = $this->client->getDriverTrips($params); 442 | } 443 | 444 | public function testRequestRide() 445 | { 446 | $params = [ 447 | 'product_id' => '4bfc6c57-98c0-424f-a72e-c1e2a1d49939', 448 | 'start_latitude' => '41.85582993', 449 | 'start_longitude' => '-87.62730337', 450 | 'end_latitude' => '41.87499492', 451 | 'end_longitude' => '-87.67126465', 452 | ]; 453 | 454 | $this->client->setUseSandbox(true); 455 | 456 | $postResponse = m::mock('GuzzleHttp\Psr7\Response'); 457 | $postResponse->shouldReceive('getBody')->times(1)->andReturn('{"request_id": "852b8fdd-4369-4659-9628-e122662ad257","status": "processing","vehicle": null,"driver": null,"location": null,"eta": 5,"surge_multiplier": null}'); 458 | $postResponse->shouldReceive('getHeader')->times(3)->andReturnValues([1000, 955, strtotime("+1 day")]); 459 | 460 | $http_client = m::mock('GuzzleHttp\Client'); 461 | $http_client->shouldReceive('post') 462 | ->with($this->client->getUrlFromPath('/requests'), ['headers' => $this->client->getHeaders(), 'json' => $params]) 463 | ->times(1)->andReturn($postResponse); 464 | 465 | $this->client->setHttpClient($http_client); 466 | 467 | $request = $this->client->requestRide($params); 468 | } 469 | 470 | public function testCreateReminder() 471 | { 472 | $params = [ 473 | 'reminder_time' => '1429294463', 474 | 'phone_number' => '555-555-5555', 475 | 'event' => [ 476 | 'time' => '1429294463', 477 | 'name' => 'Frisbee with friends', 478 | 'location' => 'Dolores Park', 479 | 'latitude' => '37.759773', 480 | 'longitude' => '-122.427063', 481 | ], 482 | 'product_id' => 'a1111c8c-c720-46c3-8534-2fcdd730040d', 483 | 'trip_branding' => [ 484 | 'link_text' => 'View team roster', 485 | 'partner_deeplink' => 'partner://team/9383', 486 | ] 487 | ]; 488 | 489 | $postResponse = m::mock('GuzzleHttp\Psr7\Response'); 490 | $postResponse->shouldReceive('getBody')->times(1)->andReturn('{"event": {"name": "Frisbee with friends","location": "Dolores Park","latitude": 37.759773,"longitude": -122.427063,"time": 1429294463},"product_id": "a1111c8c-c720-46c3-8534-2fcdd730040d","reminder_id": "def-456","reminder_time": 1429294463,"reminder_status": "pending","trip_branding": {"link_text": "View team roster","partner_deeplink": "partner://team/9383"}}'); 491 | $postResponse->shouldReceive('getHeader')->times(3)->andReturn(null); 492 | 493 | $http_client = m::mock('GuzzleHttp\Client'); 494 | $http_client->shouldReceive('post') 495 | ->with($this->client->getUrlFromPath('/reminders'), ['headers' => $this->client->getHeaders(), 'json' => $params]) 496 | ->times(1)->andReturn($postResponse); 497 | 498 | $this->client->setHttpClient($http_client); 499 | 500 | $reminder = $this->client->createReminder($params); 501 | } 502 | 503 | public function testGetCurrentRequest() 504 | { 505 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 506 | $getResponse->shouldReceive('getBody')->times(1)->andReturn('{"request_id": "","status": "processing","vehicle": null,"driver": null,"location": null,"eta": 5,"surge_multiplier": null}'); 507 | $getResponse->shouldReceive('getHeader')->times(3)->andReturn(null); 508 | 509 | $http_client = m::mock('GuzzleHttp\Client'); 510 | $http_client->shouldReceive('get') 511 | ->with($this->client->getUrlFromPath('/requests/current'), ['headers' => $this->client->getHeaders()]) 512 | ->times(1)->andReturn($getResponse); 513 | 514 | $this->client->setHttpClient($http_client); 515 | 516 | $request = $this->client->getCurrentRequest(); 517 | } 518 | 519 | public function testGetRequest() 520 | { 521 | $request_id = 'mock_request_id'; 522 | 523 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 524 | $getResponse->shouldReceive('getBody')->times(1)->andReturn('{"request_id": "'.$request_id.'","status": "processing","vehicle": null,"driver": null,"location": null,"eta": 5,"surge_multiplier": null}'); 525 | $getResponse->shouldReceive('getHeader')->times(3)->andReturnValues([1000, 955, strtotime("+1 day")]); 526 | 527 | $http_client = m::mock('GuzzleHttp\Client'); 528 | $http_client->shouldReceive('get') 529 | ->with($this->client->getUrlFromPath('/requests/'.$request_id), ['headers' => $this->client->getHeaders()]) 530 | ->times(1)->andReturn($getResponse); 531 | 532 | $this->client->setHttpClient($http_client); 533 | 534 | $request = $this->client->getRequest($request_id); 535 | } 536 | 537 | public function testGetRequestReceipt() 538 | { 539 | $request_id = 'mock_request_id'; 540 | 541 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 542 | $getResponse->shouldReceive('getBody')->times(1)->andReturn('{"request_id": "b5512127-a134-4bf4-b1ba-fe9f48f56d9d", "charges": [{"name": "Base Fare", "amount": "2.20", "type": "base_fare" }, {"name": "Distance", "amount": "2.75", "type": "distance", }, {"name": "Time", "amount": "3.57", "type": "time"} ], "surge_charge" : {"name": "Surge x1.5", "amount": "4.26", "type": "surge"}, "charge_adjustments" : [{"name": "Promotion", "amount": "-2.43", "type": "promotion", }, { "name": "Safe Rides Fee", "amount": "1.00", "type": "safe_ride_fee"}, { "name": "Rounding Down", "amount": "0.78", "type": "rounding_down"}], "normal_fare": "$8.52", "subtotal": "$12.78", "total_charged": "$5.92", "total_owed": null, "currency_code": "USD", "duration": "00:11:35", "distance": "1.49", "distance_label": "miles"}'); 543 | $getResponse->shouldReceive('getHeader')->times(3)->andReturnValues([1000, 955, strtotime("+1 day")]); 544 | 545 | $http_client = m::mock('GuzzleHttp\Client'); 546 | $http_client->shouldReceive('get') 547 | ->with($this->client->getUrlFromPath('/requests/'.$request_id.'/receipt'), ['headers' => $this->client->getHeaders()]) 548 | ->times(1)->andReturn($getResponse); 549 | 550 | $this->client->setHttpClient($http_client); 551 | 552 | $receipt = $this->client->getRequestReceipt($request_id); 553 | } 554 | 555 | public function testGetRequestMap() 556 | { 557 | $request_id = 'mock_request_id'; 558 | 559 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 560 | $getResponse->shouldReceive('getBody')->times(1)->andReturn('{"request_id":"'.$request_id.'","href":"https://trip.uber.com/abc123"}'); 561 | $getResponse->shouldReceive('getHeader')->times(3)->andReturnValues([1000, 955, strtotime("+1 day")]); 562 | 563 | $http_client = m::mock('GuzzleHttp\Client'); 564 | $http_client->shouldReceive('get') 565 | ->with($this->client->getUrlFromPath('/requests/'.$request_id.'/map'), ['headers' => $this->client->getHeaders()]) 566 | ->times(1)->andReturn($getResponse); 567 | 568 | $this->client->setHttpClient($http_client); 569 | 570 | $map = $this->client->getRequestMap($request_id); 571 | } 572 | 573 | public function testCancelCurrentRequest() 574 | { 575 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 576 | $getResponse->shouldReceive('getBody')->times(1)->andReturn(null); 577 | $getResponse->shouldReceive('getHeader')->times(3)->andReturnValues([1000, 955, strtotime("+1 day")]); 578 | 579 | $http_client = m::mock('GuzzleHttp\Client'); 580 | $http_client->shouldReceive('delete') 581 | ->with($this->client->getUrlFromPath('/requests/current'), ['headers' => $this->client->getHeaders()]) 582 | ->times(1)->andReturn($getResponse); 583 | 584 | $this->client->setHttpClient($http_client); 585 | 586 | $cancel_request = $this->client->cancelCurrentRequest(); 587 | } 588 | 589 | public function testCancelReminder() 590 | { 591 | $reminderId = uniqid(); 592 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 593 | $getResponse->shouldReceive('getBody')->times(1)->andReturn(null); 594 | $getResponse->shouldReceive('getHeader')->times(3)->andReturn(null); 595 | 596 | $http_client = m::mock('GuzzleHttp\Client'); 597 | $http_client->shouldReceive('delete') 598 | ->with($this->client->getUrlFromPath('/reminders/'.$reminderId), ['headers' => $this->client->getHeaders()]) 599 | ->times(1)->andReturn($getResponse); 600 | 601 | $this->client->setHttpClient($http_client); 602 | 603 | $cancel_reminder = $this->client->cancelReminder($reminderId); 604 | } 605 | 606 | public function testCancelRequest() 607 | { 608 | $request_id = 'mock_request_id'; 609 | 610 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 611 | $getResponse->shouldReceive('getBody')->times(1)->andReturn(null); 612 | $getResponse->shouldReceive('getHeader')->times(3)->andReturnValues([1000, 955, strtotime("+1 day")]); 613 | 614 | $http_client = m::mock('GuzzleHttp\Client'); 615 | $http_client->shouldReceive('delete') 616 | ->with($this->client->getUrlFromPath('/requests/'.$request_id), ['headers' => $this->client->getHeaders()]) 617 | ->times(1)->andReturn($getResponse); 618 | 619 | $this->client->setHttpClient($http_client); 620 | 621 | $cancel_request = $this->client->cancelRequest($request_id); 622 | } 623 | 624 | public function testGetExistingProperties() 625 | { 626 | $locale = $this->client->getLocale(); 627 | 628 | $this->assertEquals($locale, getenv('UBER_LOCALE')); 629 | } 630 | 631 | public function testSetCurrentRequest() 632 | { 633 | $request_body = ['status' => uniqid()]; 634 | 635 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 636 | $getResponse->shouldReceive('getBody')->times(1)->andReturn(null); 637 | $getResponse->shouldReceive('getHeader')->times(3)->andReturnValues([1000, 955, strtotime("+1 day")]); 638 | 639 | $http_client = m::mock('GuzzleHttp\Client'); 640 | $http_client->shouldReceive('patch') 641 | ->with($this->client->getUrlFromPath('/requests/current'), ['headers' => $this->client->getHeaders(), 'json' => $request_body]) 642 | ->times(1)->andReturn($getResponse); 643 | 644 | $this->client->setHttpClient($http_client); 645 | 646 | $request = $this->client->setCurrentRequest($request_body); 647 | } 648 | 649 | public function testSetReminder() 650 | { 651 | $reminderId = uniqid(); 652 | $params = [ 653 | 'reminder_time' => '1429294463', 654 | 'phone_number' => '555-555-5555', 655 | 'event' => [ 656 | 'time' => '1429294463', 657 | 'name' => 'Frisbee with friends', 658 | 'location' => 'Dolores Park', 659 | 'latitude' => '37.759773', 660 | 'longitude' => '-122.427063', 661 | ], 662 | 'product_id' => 'a1111c8c-c720-46c3-8534-2fcdd730040d', 663 | 'trip_branding' => [ 664 | 'link_text' => 'View team roster', 665 | 'partner_deeplink' => 'partner://team/9383', 666 | ] 667 | ]; 668 | 669 | $postResponse = m::mock('GuzzleHttp\Psr7\Response'); 670 | $postResponse->shouldReceive('getBody')->times(1)->andReturn('{"event": {"name": "Frisbee with friends","location": "Dolores Park","latitude": 37.759773,"longitude": -122.427063,"time": 1429294463},"product_id": "a1111c8c-c720-46c3-8534-2fcdd730040d","reminder_id": "def-456","reminder_time": 1429294463,"reminder_status": "pending","trip_branding": {"link_text": "View team roster","partner_deeplink": "partner://team/9383"}}'); 671 | $postResponse->shouldReceive('getHeader')->times(3)->andReturn(null); 672 | 673 | $http_client = m::mock('GuzzleHttp\Client'); 674 | $http_client->shouldReceive('patch') 675 | ->with($this->client->getUrlFromPath('/reminders/'.$reminderId), ['headers' => $this->client->getHeaders(), 'json' => $params]) 676 | ->times(1)->andReturn($postResponse); 677 | 678 | $this->client->setHttpClient($http_client); 679 | 680 | $reminder = $this->client->setReminder($reminderId, $params); 681 | } 682 | 683 | public function testSetSandboxRequestSucceedsInSandboxMode() 684 | { 685 | $request_id = 'mock_request_id'; 686 | $request_body = ['status' => uniqid()]; 687 | 688 | $this->client->setUseSandbox(true); 689 | 690 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 691 | $getResponse->shouldReceive('getBody')->times(1)->andReturn(null); 692 | $getResponse->shouldReceive('getHeader')->times(3)->andReturnValues([1000, 955, strtotime("+1 day")]); 693 | 694 | $http_client = m::mock('GuzzleHttp\Client'); 695 | $http_client->shouldReceive('put') 696 | ->with($this->client->getUrlFromPath('/sandbox/requests/'.$request_id), ['headers' => $this->client->getHeaders(), 'json' => $request_body]) 697 | ->times(1)->andReturn($getResponse); 698 | 699 | $this->client->setHttpClient($http_client); 700 | 701 | $request = $this->client->setSandboxRequest($request_id, $request_body); 702 | } 703 | 704 | /** 705 | * @expectedException Stevenmaguire\Uber\Exception 706 | */ 707 | public function testSetSandboxRequestFailsOutOfSandboxMode() 708 | { 709 | $request_id = 'mock_request_id'; 710 | $request_body = ['status' => uniqid()]; 711 | 712 | $this->client->setUseSandbox(false); 713 | 714 | $request = $this->client->setSandboxRequest($request_id, $request_body); 715 | } 716 | 717 | public function testSetRequest() 718 | { 719 | $request_id = 'mock_request_id'; 720 | $request_body = ['status' => uniqid()]; 721 | 722 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 723 | $getResponse->shouldReceive('getBody')->times(1)->andReturn(null); 724 | $getResponse->shouldReceive('getHeader')->times(3)->andReturn(null); 725 | 726 | $http_client = m::mock('GuzzleHttp\Client'); 727 | $http_client->shouldReceive('patch') 728 | ->with($this->client->getUrlFromPath('/requests/'.$request_id), ['headers' => $this->client->getHeaders(), 'json' => $request_body]) 729 | ->times(1)->andReturn($getResponse); 730 | 731 | $this->client->setHttpClient($http_client); 732 | 733 | $request = $this->client->setRequest($request_id, $request_body); 734 | } 735 | 736 | public function testSetPlace() 737 | { 738 | $placeId = 'home'; 739 | $request_body = ['address' => uniqid()]; 740 | 741 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 742 | $getResponse->shouldReceive('getBody')->times(1)->andReturn('{"address": "'.$request_body['address'].'"}'); 743 | $getResponse->shouldReceive('getHeader')->times(3)->andReturn(null); 744 | 745 | $http_client = m::mock('GuzzleHttp\Client'); 746 | $http_client->shouldReceive('put') 747 | ->with($this->client->getUrlFromPath('/places/'.$placeId), ['headers' => $this->client->getHeaders(), 'json' => $request_body]) 748 | ->times(1)->andReturn($getResponse); 749 | 750 | $this->client->setHttpClient($http_client); 751 | 752 | $request = $this->client->setPlace($placeId, $request_body); 753 | } 754 | 755 | public function testSetSandboxProductSucceedsInSandboxMode() 756 | { 757 | $product_id = 'mock_request_id'; 758 | $request_body = ['surge_multiplier' => uniqid()]; 759 | 760 | $this->client->setUseSandbox(true); 761 | 762 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 763 | $getResponse->shouldReceive('getBody')->times(1)->andReturn(null); 764 | $getResponse->shouldReceive('getHeader')->times(3)->andReturnValues([1000, 955, strtotime("+1 day")]); 765 | 766 | $http_client = m::mock('GuzzleHttp\Client'); 767 | $http_client->shouldReceive('put') 768 | ->with($this->client->getUrlFromPath('/sandbox/products/'.$product_id), ['headers' => $this->client->getHeaders(), 'json' => $request_body]) 769 | ->times(1)->andReturn($getResponse); 770 | 771 | $this->client->setHttpClient($http_client); 772 | 773 | $request = $this->client->setSandboxProduct($product_id, $request_body); 774 | } 775 | 776 | /** 777 | * @expectedException Stevenmaguire\Uber\Exception 778 | */ 779 | public function testSetSandboxProductFailsOutOfSandboxMode() 780 | { 781 | $product_id = 'mock_request_id'; 782 | $request_body = ['surge_multiplier' => uniqid()]; 783 | 784 | $this->client->setUseSandbox(false); 785 | 786 | $request = $this->client->setSandboxProduct($product_id, $request_body); 787 | } 788 | 789 | public function testSetProfile() 790 | { 791 | $request_body = ['applied_promotion_codes' => uniqid()]; 792 | 793 | $getResponse = m::mock('GuzzleHttp\Psr7\Response'); 794 | $getResponse->shouldReceive('getBody')->times(1)->andReturn('{"promotion_code": "'.$request_body['applied_promotion_codes'].'","description": "$20.00 has been applied to your account."}'); 795 | $getResponse->shouldReceive('getHeader')->times(3)->andReturn(null); 796 | 797 | $http_client = m::mock('GuzzleHttp\Client'); 798 | $http_client->shouldReceive('patch') 799 | ->with($this->client->getUrlFromPath('/me'), ['headers' => $this->client->getHeaders(), 'json' => $request_body]) 800 | ->times(1)->andReturn($getResponse); 801 | 802 | $this->client->setHttpClient($http_client); 803 | 804 | $request = $this->client->setProfile($request_body); 805 | } 806 | 807 | /** 808 | * @expectedException Stevenmaguire\Uber\Exception 809 | */ 810 | public function testGetNonExistingProperties() 811 | { 812 | $result = $this->client->{'get'.rand(1111,9999)}(); 813 | } 814 | 815 | public function testSetExistingProperties() 816 | { 817 | $var = uniqid(); 818 | $locale = $this->client->setLocale($var)->getLocale(); 819 | 820 | $this->assertEquals($locale, $var); 821 | } 822 | 823 | /** 824 | * @expectedException Stevenmaguire\Uber\Exception 825 | */ 826 | public function testSetNonExistingProperties() 827 | { 828 | $result = $this->client->{'set'.rand(1111,9999)}(); 829 | } 830 | 831 | /** 832 | * @expectedException Stevenmaguire\Uber\Exception 833 | */ 834 | public function testThrowsExceptionOnHttpErrors() 835 | { 836 | $params = []; 837 | $responseCode = 429; 838 | $responseHeaders = ['Content-Length' => 0]; 839 | $mock = new MockHandler([ 840 | new Response($responseCode, $responseHeaders) 841 | ]); 842 | $handler = HandlerStack::create($mock); 843 | 844 | $http_client = new HttpClient(['handler' => $handler]); 845 | 846 | $this->client->setHttpClient($http_client); 847 | 848 | $this->client->getProducts($params); 849 | } 850 | 851 | public function testHttpExceptionsIncludeMetaFromUber() 852 | { 853 | $params = []; 854 | $responseCode = 409; 855 | $responseReason = "Conflict"; 856 | $responsePayload = '{"meta":{"surge_confirmation":{"href":"https:\/\/api.uber.com\/v1\/surge-confirmations\/e100a670","surge_confirmation_id":"e100a670"}},"errors":[{"status":'.$responseCode.',"code":"surge","title":"Surge pricing is currently in effect for this product."}]}'; 857 | $responseHeaders = [ 858 | "Content-Type" => "application/json; charset=UTF-8", 859 | "Content-Length" => strlen($responsePayload), 860 | "Accept" => "application/json" 861 | ]; 862 | 863 | $mock = new MockHandler([ 864 | new Response($responseCode, $responseHeaders, $responsePayload) 865 | ]); 866 | $handler = HandlerStack::create($mock); 867 | 868 | $http_client = new HttpClient(['handler' => $handler]); 869 | 870 | $this->client->setHttpClient($http_client); 871 | 872 | try { 873 | $this->client->getProducts($params); 874 | } catch (\Stevenmaguire\Uber\Exception $e) { 875 | $this->assertContains($responseReason, $e->getMessage()); 876 | $this->assertEquals($responseCode, $e->getCode()); 877 | $this->assertEquals($responsePayload, json_encode($e->getBody())); 878 | } 879 | } 880 | 881 | public function testClientExceptionsThrowUberException() 882 | { 883 | $params = []; 884 | $exception = new HttpClientException( 885 | uniqid(), 886 | m::mock('Psr\Http\Message\RequestInterface') 887 | ); 888 | $http_client = m::mock('GuzzleHttp\Client'); 889 | $http_client->shouldReceive('get')->times(1)->andThrow($exception); 890 | 891 | $this->client->setHttpClient($http_client); 892 | 893 | try { 894 | $products = $this->client->getProducts($params); 895 | } catch (\Stevenmaguire\Uber\Exception $e) { 896 | $this->assertEquals(500, $e->getCode()); 897 | } 898 | } 899 | } 900 | --------------------------------------------------------------------------------