diff options
author | Christian Cleberg <hello@cleberg.net> | 2023-05-22 15:19:08 -0500 |
---|---|---|
committer | Christian Cleberg <hello@cleberg.net> | 2023-05-22 15:19:08 -0500 |
commit | 39e8fb2036945303836c461a61f133b0059c8991 (patch) | |
tree | 39b747cf3c9eb82af48117781a436a91f1314776 /vendor/tumblr | |
download | vox-populi-39e8fb2036945303836c461a61f133b0059c8991.tar.gz vox-populi-39e8fb2036945303836c461a61f133b0059c8991.tar.bz2 vox-populi-39e8fb2036945303836c461a61f133b0059c8991.zip |
initial commit
Diffstat (limited to 'vendor/tumblr')
-rw-r--r-- | vendor/tumblr/tumblr/.gitignore | 12 | ||||
-rw-r--r-- | vendor/tumblr/tumblr/.travis.yml | 12 | ||||
-rw-r--r-- | vendor/tumblr/tumblr/CONTRIBUTING.md | 22 | ||||
-rw-r--r-- | vendor/tumblr/tumblr/LICENSE | 202 | ||||
-rw-r--r-- | vendor/tumblr/tumblr/README.md | 109 | ||||
-rw-r--r-- | vendor/tumblr/tumblr/composer.json | 39 | ||||
-rw-r--r-- | vendor/tumblr/tumblr/lib/Tumblr/API/Client.php | 502 | ||||
-rw-r--r-- | vendor/tumblr/tumblr/lib/Tumblr/API/RequestException.php | 35 | ||||
-rw-r--r-- | vendor/tumblr/tumblr/lib/Tumblr/API/RequestHandler.php | 151 | ||||
-rw-r--r-- | vendor/tumblr/tumblr/phpunit.xml | 15 | ||||
-rw-r--r-- | vendor/tumblr/tumblr/test/BlogTest.php | 67 | ||||
-rw-r--r-- | vendor/tumblr/tumblr/test/PostTest.php | 30 | ||||
-rw-r--r-- | vendor/tumblr/tumblr/test/RequestExceptionTest.php | 28 | ||||
-rw-r--r-- | vendor/tumblr/tumblr/test/RequestHandlerTest.php | 71 | ||||
-rw-r--r-- | vendor/tumblr/tumblr/test/TaggedTest.php | 16 | ||||
-rw-r--r-- | vendor/tumblr/tumblr/test/TumblrTest.php | 51 | ||||
-rw-r--r-- | vendor/tumblr/tumblr/test/UserTest.php | 40 | ||||
-rw-r--r-- | vendor/tumblr/tumblr/test/bootstrap.php | 8 |
18 files changed, 1410 insertions, 0 deletions
diff --git a/vendor/tumblr/tumblr/.gitignore b/vendor/tumblr/tumblr/.gitignore new file mode 100644 index 0000000..2e61014 --- /dev/null +++ b/vendor/tumblr/tumblr/.gitignore @@ -0,0 +1,12 @@ +coverage +.DS_Store + +composer.phar + +*.swp +*.swo + +usage.php + +vendor +composer.lock diff --git a/vendor/tumblr/tumblr/.travis.yml b/vendor/tumblr/tumblr/.travis.yml new file mode 100644 index 0000000..4986ae4 --- /dev/null +++ b/vendor/tumblr/tumblr/.travis.yml @@ -0,0 +1,12 @@ +language: php +before_script: composer install + +php: + - 7.1 + - 7.0 + - 5.6 + - hhvm + +matrix: + allow_failures: + - php: hhvm diff --git a/vendor/tumblr/tumblr/CONTRIBUTING.md b/vendor/tumblr/tumblr/CONTRIBUTING.md new file mode 100644 index 0000000..e6d97d1 --- /dev/null +++ b/vendor/tumblr/tumblr/CONTRIBUTING.md @@ -0,0 +1,22 @@ +# Contributing + +We want to make contributing to tumblr.php as easy and transparent as possible. If you run into problems, please open an issue. We also actively welcome pull requests. + +## Pull Requests + +1. Fork the repo and create your branch from `master`. +2. If you've added code that should be tested, add tests. +3. If you've changed APIs, update the documentation. +4. Ensure the test suite passes. +5. If you haven't already, complete the Contributor License Agreement ("CLA"). + +## Contributor License Agreement ("CLA") + +In order to accept your pull request, we need you to submit a CLA. + +Complete your CLA [here](http://static.tumblr.com/zyubucd/GaTngbrpr/tumblr_corporate_contributor_license_agreement_v1__10-7-14.pdf) (a more integrated web form is coming soon). + +## License + +By contributing to tumblr.php you agree that your contributions will be licensed under its Apache 2.0 license. + diff --git a/vendor/tumblr/tumblr/LICENSE b/vendor/tumblr/tumblr/LICENSE new file mode 100644 index 0000000..ba74d5c --- /dev/null +++ b/vendor/tumblr/tumblr/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2013 Tumblr, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/tumblr/tumblr/README.md b/vendor/tumblr/tumblr/README.md new file mode 100644 index 0000000..69a9dd1 --- /dev/null +++ b/vendor/tumblr/tumblr/README.md @@ -0,0 +1,109 @@ +# tumblr.php + +[](http://travis-ci.org/tumblr/tumblr.php) + +The official PHP client for the +[Tumblr API](http://www.tumblr.com/docs/en/api/v2). + +## Usage + +### Basic Usage + +The first step is setting up a Client: + +``` php +$client = new Tumblr\API\Client($consumerKey, $consumerSecret); +$client->setToken($token, $tokenSecret); +``` + +And then you can do anything you'd like: + +``` php +foreach ($client->getUserInfo()->user->blogs as $blog) { + echo $blog->name . "\n"; +} +``` + +### User Methods + +``` php +$client->getUserInfo(); + +$client->getDashboardPosts($options = null); +$client->getLikedPosts($options = null); +$client->getFollowedBlogs($options = null); + +$client->follow($blogName); +$client->unfollow($blogName); + +$client->like($postId, $reblogKey); +$client->unlike($postId, $reblogKey); +``` + +### Blog Methods + +``` php +$client->getBlogInfo($blogName); + +$client->getBlogAvatar($blogName, $size = null); + +$client->getBlogPosts($blogName, $options = null); +$client->getBlogLikes($blogName, $options = null); +$client->getBlogFollowers($blogName, $options = null); + +$client->getQueuedPosts($blogName, $options = null); +$client->getDraftPosts($blogName, $options = null); +$client->getSubmissionPosts($blogName, $options = null); +``` + +### Post Methods + +``` php +$client->createPost($blogName, $data); +$client->editPost($blogName, $id, $data); +$client->deletePost($blogName, $id, $reblogKey); +$client->reblogPost($blogName, $id, $reblogKey, $options = null); +``` + +### Tagged Methods + +``` php +$client->getTaggedPosts($tag, $options = null); +``` + +## Dependencies + +tumblr.php is available +[on composer](https://packagist.org/packages/tumblr/tumblr) + +* guzzle/guzzle 6.* +* eher/oauth 1.0.x + +If you're using composer (you should!) you can just run +`php composer.phar install` and you'll be good to go. More details on +[getcomposer.org](http://getcomposer.org/). + +## Running tests + +tumblr.php has full unit tests that can be run with PHPUnit like this: + +``` bash +$ phpunit +``` + +That will also generate a coverage report into `./coverage` + +## Copyright and license + +Copyright 2013 Tumblr, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); you may not +use this work except in compliance with the License. You may obtain a copy of +the License in the LICENSE file, or at: + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +License for the specific language governing permissions and limitations. diff --git a/vendor/tumblr/tumblr/composer.json b/vendor/tumblr/tumblr/composer.json new file mode 100644 index 0000000..748a16b --- /dev/null +++ b/vendor/tumblr/tumblr/composer.json @@ -0,0 +1,39 @@ +{ + + "name": "tumblr/tumblr", + + "description": "Official Tumblr PHP Client", + + "keywords": ["tumblr", "api", "sdk", "gif"], + + "homepage": "https://github.com/tumblr/tumblr.php", + + "authors": [ + { + "name": "John Crepezzi", + "email": "john.crepezzi@gmail.com", + "homepage": "https://github.com/seejohnrun", + "role": "developer" + } + ], + + "license": "Apache-2.0", + + "type": "library", + + "require": { + "eher/oauth": "1.0.*", + "guzzlehttp/guzzle": "6.*" + }, + + "require-dev": { + "phpunit/phpunit": "5.3.*" + }, + + "autoload": { + "psr-0": { + "Tumblr\\API": "lib" + } + } + +} diff --git a/vendor/tumblr/tumblr/lib/Tumblr/API/Client.php b/vendor/tumblr/tumblr/lib/Tumblr/API/Client.php new file mode 100644 index 0000000..7d51138 --- /dev/null +++ b/vendor/tumblr/tumblr/lib/Tumblr/API/Client.php @@ -0,0 +1,502 @@ +<?php + +namespace Tumblr\API; + +/** + * A client to access the Tumblr API + */ +class Client +{ + + private $apiKey; + + /** + * Create a new Client + * + * @param string $consumerKey the consumer key + * @param string $consumerSecret the consumer secret + * @param string $token oauth token + * @param string $secret oauth token secret + */ + public function __construct($consumerKey, $consumerSecret = null, $token = null, $secret = null) + { + $this->requestHandler = new RequestHandler(); + $this->setConsumer($consumerKey, $consumerSecret); + + if ($token && $secret) { + $this->setToken($token, $secret); + } + } + + /** + * Set the consumer for this client + * + * @param string $consumerKey the consumer key + * @param string $consumerSecret the consumer secret + */ + public function setConsumer($consumerKey, $consumerSecret) + { + $this->apiKey = $consumerKey; + $this->requestHandler->setConsumer($consumerKey, $consumerSecret); + } + + /** + * Set the token for this client + * + * @param string $token the oauth token + * @param string $secret the oauth secret + */ + public function setToken($token, $secret) + { + $this->requestHandler->setToken($token, $secret); + } + + /** + * Retrieve RequestHandler instance + * + * @return RequestHandler + */ + public function getRequestHandler() + { + return $this->requestHandler; + } + + /** + * Get info on the authenticating user + * + * @return array the response array + */ + public function getUserInfo() + { + return $this->getRequest('v2/user/info', null, false); + } + + /** + * Get user dashboard for the authenticating user + * + * @param array $options the options for the call + * @return array the response array + */ + public function getDashboardPosts($options = null) + { + return $this->getRequest('v2/user/dashboard', $options, false); + } + + /** + * Get followings for the authenticating user + * + * @param array $options the options for the call + * @return array the response array + */ + public function getFollowedBlogs($options = null) + { + return $this->getRequest('v2/user/following', $options, false); + } + + /** + * Get likes for the authenticating user + * + * @param array $options the options for the call + * @return array the response array + */ + public function getLikedPosts($options = null) + { + return $this->getRequest('v2/user/likes', $options, false); + } + + /** + * Follow a blog + * + * @param string $blogName the name of the blog to follow + * @return array the response array + */ + public function follow($blogName) + { + $options = array('url' => $this->blogUrl($blogName)); + + return $this->postRequest('v2/user/follow', $options, false); + } + + /** + * Unfollow a blog + * + * @param string $blogName the name of the blog to follow + * @return array the response array + */ + public function unfollow($blogName) + { + $options = array('url' => $this->blogUrl($blogName)); + + return $this->postRequest('v2/user/unfollow', $options, false); + } + + /** + * Like a post + * + * @param int $postId the id of the post + * @param string $reblogKey the reblog_key of the post + * + * @return array the response array + */ + public function like($postId, $reblogKey) + { + $options = array('id' => $postId, 'reblog_key' => $reblogKey); + + return $this->postRequest('v2/user/like', $options, false); + } + + /** + * Unlike a post + * + * @param int $postId the id of the post + * @param string $reblogKey the reblog_key of the post + * + * @return array the response array + */ + public function unlike($postId, $reblogKey) + { + $options = array('id' => $postId, 'reblog_key' => $reblogKey); + + return $this->postRequest('v2/user/unlike', $options, false); + } + + /** + * Delete a post + * + * @param string $blogName the name of the blog the post is on + * @param int $postId the id of the post + * @param string $reblogKey the reblog_key of the post + * + * @return array the response array + */ + public function deletePost($blogName, $postId, $reblogKey) + { + $options = array('id' => $postId, 'reblog_key' => $reblogKey); + $path = $this->blogPath($blogName, '/post/delete'); + + return $this->postRequest($path, $options, false); + } + + /** + * Reblog a post + * + * @param string $blogName the name of the blog + * @param int $postId the id of the post + * @param string $reblogKey the reblog key of the post + * @param array $options the options for the call + * + * @return array the response array + */ + public function reblogPost($blogName, $postId, $reblogKey, $options = null) + { + $params = array('id' => $postId, 'reblog_key' => $reblogKey); + $params = array_merge($options ?: array(), $params); + $path = $this->blogPath($blogName, '/post/reblog'); + + return $this->postRequest($path, $params, false); + } + + /** + * Edit a post + * + * @param string $blogName the name of the blog + * @param int $postId the id of the post to edit + * @param array $data the data to save + * + * @return array the response array + */ + public function editPost($blogName, $postId, $data) + { + $data['id'] = $postId; + $path = $this->blogPath($blogName, '/post/edit'); + + return $this->postRequest($path, $data, false); + } + + /** + * Create a post + * + * @param string $blogName the name of the blog + * @param array $data the data to save + * + * @return array the response array + */ + public function createPost($blogName, $data) + { + $path = $this->blogPath($blogName, '/post'); + + return $this->postRequest($path, $data, false); + } + + /** + * Get tagged posts + * + * @param string $tag the tag to look up + * @param array $options the options for the call + * + * @return array the response array + */ + public function getTaggedPosts($tag, $options = null) + { + if (!$options) { + $options = array(); + } + $options['tag'] = $tag; + + return $this->getRequest('v2/tagged', $options, true); + } + + /** + * Get information about a given blog + * + * @param string $blogName the name of the blog to look up + * @return array the response array + */ + public function getBlogInfo($blogName) + { + $path = $this->blogPath($blogName, '/info'); + + return $this->getRequest($path, null, true); + } + + /** + * Get blog avatar URL + * + * @param string $blogName the nae of the blog to look up + * @param int $size the size to retrieve + * + * @return string the avatar url + */ + public function getBlogAvatar($blogName, $size = null) + { + $path = $this->blogPath($blogName, '/avatar'); + if ($size) { + $path .= "/$size"; + } + + return $this->getRedirect($path, null, true); + } + + /** + * Get blog likes for a given blog + * + * @param string $blogName the name of the blog to look up + * @param array $options the options for the call + * + * @return array the response array + */ + public function getBlogLikes($blogName, $options = null) + { + $path = $this->blogPath($blogName, '/likes'); + + return $this->getRequest($path, $options, true); + } + + /** + * Get blog followers for a given blog + * + * @param string $blogName the name of the blog to look up + * @param array $options the options for the call + * + * @return array the response array + */ + public function getBlogFollowers($blogName, $options = null) + { + $path = $this->blogPath($blogName, '/followers'); + + return $this->getRequest($path, $options, false); + } + + /** + * Get posts for a given blog + * + * @param string $blogName the name of the blog + * @param array $options the options for the call + * + * @return array the response array + */ + public function getBlogPosts($blogName, $options = null) + { + $path = $this->blogPath($blogName, '/posts'); + if ($options && isset($options['type'])) { + $path .= '/' . $options['type']; + unset($options['type']); + } + + return $this->getRequest($path, $options, true); + } + + /** + * Get queue posts for a given blog + * + * @param string $blogName the name of the blog + * @param array $options the options for the call + * + * @return array the response array + */ + public function getQueuedPosts($blogName, $options = null) + { + $path = $this->blogPath($blogName, '/posts/queue'); + + return $this->getRequest($path, $options, false); + } + + /** + * Get draft posts for a given blog + * + * @param string $blogName the name of the blog + * @param array $options the options for the call + * + * @return array the response array + */ + public function getDraftPosts($blogName, $options = null) + { + $path = $this->blogPath($blogName, '/posts/draft'); + + return $this->getRequest($path, $options, false); + } + + /** + * Get submission posts for a given blog + * + * @param string $blogName the name of the blog + * @param array $options the options for the call + * + * @return array the response array + */ + public function getSubmissionPosts($blogName, $options = null) + { + $path = $this->blogPath($blogName, '/posts/submission'); + + return $this->getRequest($path, $options, false); + } + + /** + * Make a GET request to the given endpoint and return the response + * + * @param string $path the path to call on + * @param array $options the options to call with + * @param bool $addApiKey whether or not to add the api key + * + * @return array the response object (parsed) + */ + public function getRequest($path, $options, $addApiKey) + { + $response = $this->makeRequest('GET', $path, $options, $addApiKey); + + return $this->parseResponse($response); + } + + /** + * Make a POST request to the given endpoint and return the response + * + * @param string $path the path to call on + * @param array $options the options to call with + * @param bool $addApiKey whether or not to add the api key + * + * @return array the response object (parsed) + */ + public function postRequest($path, $options, $addApiKey) + { + if (isset($options['source']) && is_array($options['source'])) { + $sources = $options['source']; + unset($options['source']); + foreach ($sources as $i => $source) { + $options["source[$i]"] = $source; + } + } + + $response = $this->makeRequest('POST', $path, $options, $addApiKey); + return $this->parseResponse($response); + } + + /** + * Parse a response and return an appropriate result + * + * @param \stdClass $response the response from the server + * + * @throws RequestException + * @return array the response data + */ + private function parseResponse($response) + { + $response->json = json_decode($response->body); + if ($response->status < 400) { + return $response->json->response; + } else { + throw new RequestException($response); + } + } + + /** + * Make a GET request to the given endpoint and return the response + * + * @param string $path the path to call on + * @param array $options the options to call with + * @param bool $addApiKey whether or not to add the api key + * + * @return string url redirected to (or null) + */ + private function getRedirect($path, $options, $addApiKey) + { + $response = $this->makeRequest('GET', $path, $options, $addApiKey); + if ($response->status === 301 || $response->status === 302) { + return $response->headers['Location'][0]; + } + + return null; + } + + /** + * Make a request to the given endpoint and return the response + * + * @param string $method the method to call: GET, POST + * @param string $path the path to call on + * @param array $options the options to call with + * @param bool $addApiKey whether or not to add the api key + * + * @return \stdClass the response object (not parsed) + */ + private function makeRequest($method, $path, $options, $addApiKey) + { + if ($addApiKey) { + $options = array_merge( + array('api_key' => $this->apiKey), + $options ?: array() + ); + } + + return $this->requestHandler->request($method, $path, $options); + } + + /** + * Expand the given blogName into a base path for the blog + * + * @param string $blogName the name of the blog + * @param string $ext the url extension + * + * @return string the blog base path + */ + private function blogPath($blogName, $ext) + { + $blogUrl = $this->blogUrl($blogName); + + return "v2/blog/$blogUrl$ext"; + } + + /** + * Get the URL of a blog by name or URL + * + * @param string $blogName the name of the blog + * @return string the blog URL + */ + private function blogUrl($blogName) + { + if (strpos($blogName, '.') === false) { + return "$blogName.tumblr.com"; + } + + return $blogName; + } + +} diff --git a/vendor/tumblr/tumblr/lib/Tumblr/API/RequestException.php b/vendor/tumblr/tumblr/lib/Tumblr/API/RequestException.php new file mode 100644 index 0000000..00af04b --- /dev/null +++ b/vendor/tumblr/tumblr/lib/Tumblr/API/RequestException.php @@ -0,0 +1,35 @@ +<?php + +namespace Tumblr\API; + +class RequestException extends \Exception +{ + + /** + * @param \stdClass $response + */ + public function __construct($response) + { + $error = json_decode($response->body); + + $errstr = 'Unknown Error'; + if (isset($error->meta)) { + $errstr = $error->meta->msg; + if (isset($error->response->errors)) { + $errstr .= ' ('.$error->response->errors[0].')'; + } + } elseif (isset($error->response->errors)) { + $errstr = $error->response->errors[0]; + } + + $this->statusCode = $response->status; + $this->message = $errstr; + parent::__construct($this->message, $this->statusCode); + } + + public function __toString() + { + return __CLASS__ . ": [$this->statusCode]: $this->message\n"; + } + +} diff --git a/vendor/tumblr/tumblr/lib/Tumblr/API/RequestHandler.php b/vendor/tumblr/tumblr/lib/Tumblr/API/RequestHandler.php new file mode 100644 index 0000000..c14eefc --- /dev/null +++ b/vendor/tumblr/tumblr/lib/Tumblr/API/RequestHandler.php @@ -0,0 +1,151 @@ +<?php + +namespace Tumblr\API; + +/** + * A request handler for Tumblr authentication + * and requests + */ +class RequestHandler +{ + + private $consumer; + private $token; + private $signatureMethod; + + private $baseUrl; + private $version; + + /** + * Instantiate a new RequestHandler + */ + public function __construct() + { + $this->baseUrl = 'https://api.tumblr.com/'; + $this->version = '0.1.2'; + + $this->signatureMethod = new \Eher\OAuth\HmacSha1(); + $this->client = new \GuzzleHttp\Client(array( + 'allow_redirects' => false, + )); + } + + /** + * Set the consumer for this request handler + * + * @param string $key the consumer key + * @param string $secret the consumer secret + */ + public function setConsumer($key, $secret) + { + $this->consumer = new \Eher\OAuth\Consumer($key, $secret); + } + + /** + * Set the token for this request handler + * + * @param string $token the oauth token + * @param string $secret the oauth secret + */ + public function setToken($token, $secret) + { + $this->token = new \Eher\OAuth\Token($token, $secret); + } + + /** + * Set the base url for this request handler. + * + * @param string $url The base url (e.g. https://api.tumblr.com) + */ + public function setBaseUrl($url) + { + // Ensure we have a trailing slash since it is expected in {@link request}. + if (substr($url, -1) !== '/') { + $url .= '/'; + } + + $this->baseUrl = $url; + } + + /** + * Make a request with this request handler + * + * @param string $method one of GET, POST + * @param string $path the path to hit + * @param array $options the array of params + * + * @return \stdClass response object + */ + public function request($method, $path, $options) + { + // Ensure we have options + $options = $options ?: array(); + + // Take off the data param, we'll add it back after signing + $file = isset($options['data']) ? $options['data'] : false; + unset($options['data']); + + // Get the oauth signature to put in the request header + $url = $this->baseUrl . $path; + $oauth = \Eher\OAuth\Request::from_consumer_and_token( + $this->consumer, + $this->token, + $method, + $url, + $options + ); + $oauth->sign_request($this->signatureMethod, $this->consumer, $this->token); + $authHeader = $oauth->to_header(); + $pieces = explode(' ', $authHeader, 2); + $authString = $pieces[1]; + + + // Set up the request and get the response + $uri = new \GuzzleHttp\Psr7\Uri($url); + $guzzleOptions = [ + 'headers' => [ + 'Authorization' => $authString, + 'User-Agent' => 'tumblr.php/' . $this->version, + ], + // Swallow exceptions since \Tumblr\API\Client will handle them + 'http_errors' => false, + ]; + if ($method === 'GET') { + $uri = $uri->withQuery(http_build_query($options)); + } elseif ($method === 'POST') { + if (!$file) { + $guzzleOptions['form_params'] = $options; + } else { + // Add the files back now that we have the signature without them + $content_type = 'multipart'; + $form = []; + foreach ($options as $name => $contents) { + $form[] = [ + 'name' => $name, + 'contents' => $contents, + ]; + } + foreach ((array) $file as $idx => $path) { + $form[] = [ + 'name' => "data[$idx]", + 'contents' => file_get_contents($path), + 'filename' => pathinfo($path, PATHINFO_FILENAME), + ]; + } + $guzzleOptions['multipart'] = $form; + } + } + + $response = $this->client->request($method, $uri, $guzzleOptions); + + // Construct the object that the Client expects to see, and return it + $obj = new \stdClass; + $obj->status = $response->getStatusCode(); + // Turn the stream into a string + $obj->body = $response->getBody()->__toString(); + $obj->headers = $response->getHeaders(); + + return $obj; + } + +} diff --git a/vendor/tumblr/tumblr/phpunit.xml b/vendor/tumblr/tumblr/phpunit.xml new file mode 100644 index 0000000..2e7968c --- /dev/null +++ b/vendor/tumblr/tumblr/phpunit.xml @@ -0,0 +1,15 @@ +<phpunit bootstrap="test/bootstrap.php" colors="true"> + <testsuites> + <testsuite name="Tumblr SDK for PHP - Test Suite"> + <directory>test</directory> + </testsuite> + </testsuites> + <filter> + <whitelist> + <directory suffix=".php">lib</directory> + </whitelist> + </filter> + <logging> + <log type="coverage-html" target="./coverage" highlight="true"/> + </logging> +</phpunit> diff --git a/vendor/tumblr/tumblr/test/BlogTest.php b/vendor/tumblr/tumblr/test/BlogTest.php new file mode 100644 index 0000000..22a63bf --- /dev/null +++ b/vendor/tumblr/tumblr/test/BlogTest.php @@ -0,0 +1,67 @@ +<?php + +class BlogTest extends TumblrTest +{ + public function providerCalls() + { + $test = $this; // for inner context + + return array( + + // getBlogInfo + array(function ($c) { $c->getBlogInfo('b'); }, 'GET', 'v2/blog/b.tumblr.com/info', array('api_key' => API_KEY)), + + // getBlogAvatar + array(function ($c) use ($test) { + $url = $c->getBlogAvatar('b'); + $test->assertEquals($url, 'url'); + }, 'GET', 'v2/blog/b.tumblr.com/avatar', array('api_key' => API_KEY), 'redirect'), + array(function ($c) use ($test) { + $url = $c->getBlogAvatar('b'); + $test->assertEquals($url, null); + }, 'GET', 'v2/blog/b.tumblr.com/avatar', array('api_key' => API_KEY), 'not_found'), + array(function ($c) { $c->getBlogAvatar('b', 128); }, 'GET', 'v2/blog/b.tumblr.com/avatar/128', array('api_key' => API_KEY)), + + // getBlogLikes + array(function ($c) { $c->getBlogLikes('b.n'); }, 'GET', 'v2/blog/b.n/likes', array('api_key' => API_KEY)), + array(function ($c) { $c->getBlogLikes('b.n', array('limit' => 10)); }, 'GET', 'v2/blog/b.n/likes', array('limit' => 10, 'api_key' => API_KEY)), + + // getBlogFollowers + array(function ($c) { $c->getBlogFollowers('b.n'); }, 'GET', 'v2/blog/b.n/followers', null), + array(function ($c) { $c->getBlogFollowers('b.n', array('limit' => 10)); }, 'GET', 'v2/blog/b.n/followers', array('limit' => 10)), + + // getBlogPosts + array(function ($c) { $c->getBlogPosts('b.n'); }, 'GET', 'v2/blog/b.n/posts', array('api_key' => API_KEY)), + array(function ($c) { $c->getBlogPosts('b.n', array('limit' => 10)); }, 'GET', 'v2/blog/b.n/posts', array('limit' => 10, 'api_key' => API_KEY)), + array(function ($c) { $c->getBlogPosts('b.n', array('type' => 'text')); }, 'GET', 'v2/blog/b.n/posts/text', array('api_key' => API_KEY)), + + // getQueuedPosts + array(function ($c) { $c->getQueuedPosts('b.n'); }, 'GET', 'v2/blog/b.n/posts/queue', null), + array(function ($c) { $c->getQueuedPosts('b.n', array('limit' => 10)); }, 'GET', 'v2/blog/b.n/posts/queue', array('limit' => 10)), + + // getDraftPosts + array(function ($c) { $c->getDraftPosts('b.n'); }, 'GET', 'v2/blog/b.n/posts/draft', null), + array(function ($c) { $c->getDraftPosts('b.n', array('limit' => 10)); }, 'GET', 'v2/blog/b.n/posts/draft', array('limit' => 10)), + + // getSubmissionPosts + array(function ($c) { $c->getSubmissionPosts('b.n'); }, 'GET', 'v2/blog/b.n/posts/submission', null), + array(function ($c) { $c->getSubmissionPosts('b.n', array('limit' => 10)); }, 'GET', 'v2/blog/b.n/posts/submission', array('limit' => 10)), + + ); + } + + public function testNotFound() + { + try { + $this->testCalls(function ($c) { + $c->getBlogInfo('b'); + }, 'GET', 'v2/blog/b.tumblr.com/info', array('api_key' => API_KEY), 'not_found'); + } catch (\Tumblr\API\RequestException $e) { + $this->assertEquals((string) $e, "Tumblr\API\RequestException: [404]: Unknown Error\n"); + + return; + } + $this->fail('no error thrown'); + } + +} diff --git a/vendor/tumblr/tumblr/test/PostTest.php b/vendor/tumblr/tumblr/test/PostTest.php new file mode 100644 index 0000000..55d1bdb --- /dev/null +++ b/vendor/tumblr/tumblr/test/PostTest.php @@ -0,0 +1,30 @@ +<?php + +class PostTest extends TumblrTest +{ + public function providerCalls() + { + return array( + + // delete post + array(function ($c) { $c->deletePost('b', 123, 'abc'); }, 'POST', 'v2/blog/b.tumblr.com/post/delete', array('id' => 123, 'reblog_key' => 'abc')), + + // reblog post + array(function ($c) { $c->reblogPost('b', 123, 'abc'); }, 'POST', 'v2/blog/b.tumblr.com/post/reblog', array('id' => 123, 'reblog_key' => 'abc')), + array(function ($c) { $c->reblogPost('b', 123, 'abc', array('something' => 'else')); }, 'POST', 'v2/blog/b.tumblr.com/post/reblog', array('id' => 123, 'reblog_key' => 'abc', 'something' => 'else')), + + // edit post + array(function ($c) { $c->editPost('b.n', 123, array('d' => 'ata')); }, 'POST', 'v2/blog/b.n/post/edit', array('d' => 'ata', 'id' => 123)), + + // create post + array(function ($c) { $c->createPost('b.n', array('d' => 'ata')); }, 'POST', 'v2/blog/b.n/post', array('d' => 'ata')), + + // single source + array(function ($c) { $c->createPost('b.n', array('source' => 'remote')); }, 'POST', 'v2/blog/b.n/post', array('source' => 'remote')), + + // multi-source + array(function ($c) { $c->createPost('b.n', array('source' => array('r1', 'r2'))); }, 'POST', 'v2/blog/b.n/post', array('source[0]' => 'r1', 'source[1]' => 'r2')), + + ); + } +} diff --git a/vendor/tumblr/tumblr/test/RequestExceptionTest.php b/vendor/tumblr/tumblr/test/RequestExceptionTest.php new file mode 100644 index 0000000..6180bca --- /dev/null +++ b/vendor/tumblr/tumblr/test/RequestExceptionTest.php @@ -0,0 +1,28 @@ +<?php + +class RequestExceptionTest extends PHPUnit_Framework_TestCase +{ + public function provider() + { + $class_name = 'Tumblr\API\RequestException'; + + return array( + + array(array('status' => 401, 'body' => '{}'), "$class_name: [401]: Unknown Error\n"), + + array(array('status' => 404, 'body' => '{"meta":{"msg":"cool story bro"}}'), "$class_name: [404]: cool story bro\n"), + + ); + } + + /** + * @dataProvider provider + */ + public function testErrorString($responseArr, $expectedString) + { + $response = (object) $responseArr; + $err = new \Tumblr\API\RequestException($response); + $this->assertEquals((string) $err, $expectedString); + } + +} diff --git a/vendor/tumblr/tumblr/test/RequestHandlerTest.php b/vendor/tumblr/tumblr/test/RequestHandlerTest.php new file mode 100644 index 0000000..4dfdcb9 --- /dev/null +++ b/vendor/tumblr/tumblr/test/RequestHandlerTest.php @@ -0,0 +1,71 @@ +<?php + +class RequestHandlerTest extends \PHPUnit_Framework_TestCase +{ + public function testBaseUrlHasTrailingSlash() + { + $client = new Tumblr\API\Client(API_KEY); + $rh = $client->getRequestHandler(); + $this->assertInstanceOf('Tumblr\API\RequestHandler', $rh); + + $rh->setBaseUrl('http://example.com'); + $this->assertAttributeEquals('http://example.com/', 'baseUrl', $rh); + + $rh->setBaseUrl('http://example.com/'); + $this->assertAttributeEquals('http://example.com/', 'baseUrl', $rh); + } + + /** + * @expectedException GuzzleHttp\Exception\ConnectException + */ + public function testRequestThrowsErrorOnMalformedBaseUrl() + { + $client = new Tumblr\API\Client(API_KEY); + $rh = $client->getRequestHandler(); + $rh->setBaseUrl('this is a malformed URL!'); + + $options = array('some kinda option'); + + $rh->request('GET', 'foo', $options); + + } + + /** + * @expectedException Tumblr\API\RequestException + * @expectedExceptionCode 400 + * @expectedExceptionMessage Sadface + */ + public function testRequestThrowsOnBadResponse() + { + // Setup mock handler and response + $mock = new GuzzleHttp\Handler\MockHandler([ + new GuzzleHttp\Psr7\Response(400, [], '{"meta": {"status": 400, "msg": "Sadface"} }'), + ]); + $stack = GuzzleHttp\HandlerStack::create($mock); + $guzzle = new GuzzleHttp\Client(['handler' => $stack]); + + // Attached mocked guzzle client + $client = new Tumblr\API\Client(API_KEY); + $client->getRequestHandler()->client = $guzzle; + + // Throws because it got a 400 back + $client->getBlogInfo('ceyko.tumblr.com'); + } + + public function testRequestGetsJsonResponseField() + { + // Setup mock handler and response + $mock = new GuzzleHttp\Handler\MockHandler([ + new GuzzleHttp\Psr7\Response(200, [], '{"meta": {"status": 200, "msg": "OK"}, "response": "Response Text"}'), + ]); + $stack = GuzzleHttp\HandlerStack::create($mock); + $guzzle = new GuzzleHttp\Client(['handler' => $stack]); + + // Attached mocked guzzle client + $client = new Tumblr\API\Client(API_KEY); + $client->getRequestHandler()->client = $guzzle; + + // Parses out the `reponse` field in json on success + $this->assertEquals($client->getBlogInfo('ceyko.tumblr.com'), 'Response Text'); + } +} diff --git a/vendor/tumblr/tumblr/test/TaggedTest.php b/vendor/tumblr/tumblr/test/TaggedTest.php new file mode 100644 index 0000000..c595508 --- /dev/null +++ b/vendor/tumblr/tumblr/test/TaggedTest.php @@ -0,0 +1,16 @@ +<?php + +class TaggedTest extends TumblrTest +{ + public function providerCalls() + { + return array( + + // getTaggedPosts + array(function ($c) { $c->getTaggedPosts('hey'); }, 'GET', 'v2/tagged', array('tag' => 'hey', 'api_key' => API_KEY)), + array(function ($c) { $c->getTaggedPosts('hey', array('limit' => 10)); }, 'GET', 'v2/tagged', array('limit' => 10, 'tag' => 'hey', 'api_key' => API_KEY)), + + ); + } + +} diff --git a/vendor/tumblr/tumblr/test/TumblrTest.php b/vendor/tumblr/tumblr/test/TumblrTest.php new file mode 100644 index 0000000..a014634 --- /dev/null +++ b/vendor/tumblr/tumblr/test/TumblrTest.php @@ -0,0 +1,51 @@ +<?php + +class TumblrTest extends PHPUnit_Framework_TestCase +{ + /** + * @dataProvider providerCalls + */ + public function testCalls($callable, $type, $path, $params, $which_mock = 'perfect') + { + // a good response + $response = $this->getResponseMock($which_mock); + + // Create request mock and set it to check for the proper response + $request = $this->getMock('Tumblr\API\RequestHandler', array('request')); + $request->expects($this->once()) + ->method('request') + ->with($this->equalTo($type), $this->equalTo($path), $this->equalTo($params)) + ->will($this->returnValue($response)); + + // Create a new client and set it up to use that request handler + $client = new Tumblr\API\Client(API_KEY); + $ref = new ReflectionObject($client); + $prop = $ref->getProperty('requestHandler'); + $prop->setAccessible(true); + $prop->setValue($client, $request); + + // Give it tokens + $client->setToken('t1', 't2'); + + // And then run the callback to check the results + $callable($client); + } + + private function getResponseMock($which) + { + $response = new stdClass; + if ($which == 'perfect') { + $response->status = 200; + $response->body = '{"response":[]}'; + } elseif ($which == 'redirect') { + $response->status = 301; + $response->headers = array('Location' => array('url')); + } elseif ($which == 'not_found') { + $response->status = 404; + $response->body = '{}'; + } + + return $response; + } + +} diff --git a/vendor/tumblr/tumblr/test/UserTest.php b/vendor/tumblr/tumblr/test/UserTest.php new file mode 100644 index 0000000..e42b336 --- /dev/null +++ b/vendor/tumblr/tumblr/test/UserTest.php @@ -0,0 +1,40 @@ +<?php + +class UserTest extends TumblrTest +{ + public function providerCalls() + { + return array( + + // getUserInfo + array(function ($c) { $c->getUserInfo(); }, 'GET', 'v2/user/info', null), + + // getDashboardPosts + array(function ($c) { $c->getDashboardPosts(); }, 'GET', 'v2/user/dashboard', null), + array(function ($c) { $c->getDashboardPosts(array('limit' => 10)); }, 'GET', 'v2/user/dashboard', array('limit' => 10)), + + // getFollowedBlogs + array(function ($c) { $c->getFollowedBlogs(); }, 'GET', 'v2/user/following', null), + array(function ($c) { $c->getFollowedBlogs(array('limit' => 10)); }, 'GET', 'v2/user/following', array('limit' => 10)), + + // getLikedPosts + array(function ($c) { $c->getLikedPosts(); }, 'GET', 'v2/user/likes', null), + array(function ($c) { $c->getLikedPosts(array('limit' => 10)); }, 'GET', 'v2/user/likes', array('limit' => 10)), + + // follow + array(function ($c) { $c->follow('b'); }, 'POST', 'v2/user/follow', array('url' => 'b.tumblr.com')), + array(function ($c) { $c->follow('b.n'); }, 'POST', 'v2/user/follow', array('url' => 'b.n')), + + // unfollow + array(function ($c) { $c->unfollow('b'); }, 'POST', 'v2/user/unfollow', array('url' => 'b.tumblr.com')), + + // like + array(function ($c) { $c->like(123, 'abc'); }, 'POST', 'v2/user/like', array('id' => 123, 'reblog_key' => 'abc')), + + // unlike + array(function ($c) { $c->unlike(123, 'abc'); }, 'POST', 'v2/user/unlike', array('id' => 123, 'reblog_key' => 'abc')), + + ); + } + +} diff --git a/vendor/tumblr/tumblr/test/bootstrap.php b/vendor/tumblr/tumblr/test/bootstrap.php new file mode 100644 index 0000000..cfa1b00 --- /dev/null +++ b/vendor/tumblr/tumblr/test/bootstrap.php @@ -0,0 +1,8 @@ +<?php + +date_default_timezone_set('America/New_York'); + +require_once 'vendor/autoload.php'; +require_once 'test/TumblrTest.php'; + +define('API_KEY', 'the testing consumer key'); |