diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index dbb5eaf..0000000 Binary files a/.DS_Store and /dev/null differ diff --git a/.gitignore b/.gitignore index 61942b9..10089d8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ vendor examples/archive.tar -test.php +*.php composer.lock .DS_Store \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..8711839 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,35 @@ +# IPFS-PHP Changelog + +This file contains information about every addition, update and deletion in the IPFS-PHP library. +It is recommended to read this file before updating the library to a new version. + +## v1.0.0 + +Initial release of the project. + +#### Additions + +- Added the `IPFS\Client\IPFSClient` class to interact with IPFS nodes + - Supports the following IPFS methods: + - `add` + - `cat` + - `get` + - `ls` + - `pin/add` + - `pin/rm` + - `version` + - `ping` + - Added the corresponding response models and transformers +- Added unit tests + +## v1.1.0 + +This releases brings support for the `CID` IPFS identifiers. + +#### Additions + +- Added the `IPFS\Service\CIDEncoder` class that allows for encoding v1 CIDs in the `bafk` format. + +#### Updates + +- Enhanced the `IPFSClient::ping` unit test to handle the actual response format from IPFS nodes. diff --git a/README.md b/README.md index 3478571..c83e975 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,8 @@ [![PHP CI](https://github.com/EdouardCourty/ipfs-php/actions/workflows/php_ci.yml/badge.svg)](https://github.com/EdouardCourty/ipfs-php/actions/workflows/php_ci.yml) -IPFS-PHP provides a simple way to interact with an IPFS Node using PHP. +IPFS-PHP provides a simple way to interact with an IPFS Node using PHP. +The changelog for this project can be found [here](./CHANGELOG.md). ## Installation diff --git a/composer.json b/composer.json index ba08aa7..e99f81d 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,8 @@ "type": "library", "require": { "php": ">= 8.3", - "symfony/http-client": "^7.2" + "symfony/http-client": "^7.2", + "selective/base32": "^2.0" }, "require-dev": { "phpunit/phpunit": "^12.0", diff --git a/src/Client/IPFSClient.php b/src/Client/IPFSClient.php index 81151e4..c3322f0 100644 --- a/src/Client/IPFSClient.php +++ b/src/Client/IPFSClient.php @@ -4,6 +4,7 @@ namespace IPFS\Client; +use IPFS\Exception\IPFSTransportException; use IPFS\Model\File; use IPFS\Model\Node; use IPFS\Model\Ping; @@ -147,7 +148,17 @@ public function ping(string $nodeId, int $count = 10): Ping ], ]); - $parsedResponse = json_decode($response, true); + $parts = explode("\n", $response); + $filtered = array_filter($parts, function (string $value) { + return mb_strlen(trim($value)) > 0; + }); + + if (empty($filtered) === true) { + throw new IPFSTransportException('Unable to decode ping response.'); + } + + $realResponse = (string) $filtered[\count($filtered) - 1]; + $parsedResponse = json_decode($realResponse, true); $pingTransformer = new PingTransformer(); return $pingTransformer->transform($parsedResponse); diff --git a/src/Service/CIDEncoder.php b/src/Service/CIDEncoder.php new file mode 100644 index 0000000..de016e4 --- /dev/null +++ b/src/Service/CIDEncoder.php @@ -0,0 +1,31 @@ +encode($cidBinary, false); + return 'b' . mb_strtolower($cidBase32); + } + + /** + * Compute the multihash using SHA-256. + */ + private static function computeMultihash(string $data): string + { + $hash = hash('sha256', $data, true); + + return pack("C*", 0x12, 0x20) . $hash; + } +} diff --git a/tests/Client/IPFSClientTest.php b/tests/Client/IPFSClientTest.php index 85a3c7d..58b3b5d 100644 --- a/tests/Client/IPFSClientTest.php +++ b/tests/Client/IPFSClientTest.php @@ -265,7 +265,9 @@ public function testPing(): void 'Time' => '1234567890', 'Text' => 'Hello, World!', ]; - + $jsonEncoded = json_encode($mockReturn); + // Ping responses contain multiple JSON objects separated by newlines. + $actualMockReturn = implode("\n", [$jsonEncoded, $jsonEncoded, $jsonEncoded]); $this->httpClient ->expects($this->once()) ->method('request') @@ -275,7 +277,7 @@ public function testPing(): void 'count' => 10, ], ]) - ->willReturn(json_encode($mockReturn)); + ->willReturn($actualMockReturn); $result = $this->client->ping('QmZ4tDuvese8GKQ3vz8Fq8bKz1q3z1z1z1z1z1z1z1z1z'); diff --git a/tests/Service/CIDEncoderTest.php b/tests/Service/CIDEncoderTest.php new file mode 100644 index 0000000..ee6762b --- /dev/null +++ b/tests/Service/CIDEncoderTest.php @@ -0,0 +1,28 @@ +assertSame($expectedCIDv1, $computedCIDv1); + } +}