diff --git a/lib/Github/Api/Repository/Contents.php b/lib/Github/Api/Repository/Contents.php index 23ffed4bbc8..95d99469949 100644 --- a/lib/Github/Api/Repository/Contents.php +++ b/lib/Github/Api/Repository/Contents.php @@ -4,6 +4,8 @@ use Github\Api\AbstractApi; use Github\Exception\MissingArgumentException; +use Github\Exception\InvalidArgumentException; +use Github\Exception\ErrorException; /** * @link http://developer.github.com/v3/repos/contents/ @@ -72,4 +74,38 @@ public function archive($username, $repository, $format, $reference = null) 'ref' => $reference )); } + + /** + * Get the contents of a file in a repository + * + * @param string $username the user who owns the repository + * @param string $repository the name of the repository + * @param string $path path to file + * @param string $reference reference to a branch or commit + * + * @return string|null content of file, or null in case of base64_decode failure + * + * @throws InvalidArgumentException If $path is not a file or if its encoding is different from base64 + * @throws ErrorException If $path doesn't include a 'content' index + */ + public function download($username, $repository, $path, $reference = null) + { + $file = $this->show($username, $repository, $path, $reference); + + if (!isset($file['type']) || 'file' !== $file['type']) { + throw new InvalidArgumentException(sprintf('Path "%s" is not a file.', $path)); + } + + if (!isset($file['content'])) { + throw new ErrorException(sprintf('Unable to access "content" for file "%s" (possible keys: "%s").', $path, implode(', ', array_keys($file)))); + } + + if (!isset($file['encoding'])) { + throw new InvalidArgumentException(sprintf('Can\t decode contents of file "%s" as no encoding is defined.', $path)); + } elseif ('base64' !== $file['encoding']) { + throw new InvalidArgumentException(sprintf('Encoding "%s" of file "%s" is not supported.', $file['encoding'], $path)); + } + + return base64_decode($file['content']) ?: null; + } } diff --git a/test/Github/Tests/Api/Repository/ContentsDownloadFixture.php b/test/Github/Tests/Api/Repository/ContentsDownloadFixture.php new file mode 100644 index 00000000000..07dece20576 --- /dev/null +++ b/test/Github/Tests/Api/Repository/ContentsDownloadFixture.php @@ -0,0 +1,6 @@ +assertEquals($expectedValue, $api->archive('KnpLabs', 'php-github-api', 'zipball')); } + + /** + * @test + */ + public function shouldDownloadForGivenPath() + { + // The show() method return + $getValue = include 'ContentsDownloadFixture.php'; + + // The download() method return + $expectedValue = base64_decode($getValue['content']); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('repos/KnpLabs/php-github-api/contents/test%2FGithub%2FTests%2FApi%2FRepository%2FContentsTest.php', array('ref' => null)) + ->will($this->returnValue($getValue)); + + $this->assertEquals($expectedValue, $api->download('KnpLabs', 'php-github-api', 'test/Github/Tests/Api/Repository/ContentsTest.php')); + } protected function getApiClass() {