Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file removed .DS_Store
Binary file not shown.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
vendor

examples/archive.tar
test.php
*.php

composer.lock
.DS_Store
35 changes: 35 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
13 changes: 12 additions & 1 deletion src/Client/IPFSClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace IPFS\Client;

use IPFS\Exception\IPFSTransportException;
use IPFS\Model\File;
use IPFS\Model\Node;
use IPFS\Model\Ping;
Expand Down Expand Up @@ -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);
Expand Down
31 changes: 31 additions & 0 deletions src/Service/CIDEncoder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace IPFS\Service;

use Selective\Base32\Base32;

class CIDEncoder
{
private const int RAW_CODEC = 0x55;

public static function computeCIDv1(string $data): string
{
$multihash = self::computeMultihash($data);
$cidBinary = pack("C*", 0x01, self::RAW_CODEC) . $multihash;

$cidBase32 = (new Base32())->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;
}
}
6 changes: 4 additions & 2 deletions tests/Client/IPFSClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand All @@ -275,7 +277,7 @@ public function testPing(): void
'count' => 10,
],
])
->willReturn(json_encode($mockReturn));
->willReturn($actualMockReturn);

$result = $this->client->ping('QmZ4tDuvese8GKQ3vz8Fq8bKz1q3z1z1z1z1z1z1z1z1z');

Expand Down
28 changes: 28 additions & 0 deletions tests/Service/CIDEncoderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace IPFS\Tests\Service;

use IPFS\Service\CIDEncoder;
use PHPUnit\Framework\TestCase;

/**
* @coversDefaultClass \IPFS\Service\CIDEncoder
*/
class CIDEncoderTest extends TestCase
{
/**
* @covers ::computeCIDv1
* @covers ::computeMultihash
*/
public function testItEncodes(): void
{
$data = 'Hello, world!';

$expectedCIDv1 = 'bafkreibrl5n5w5wqpdcdxcwaazheualemevr7ttxzbutiw74stdvrfhn2m';
$computedCIDv1 = CIDEncoder::computeCIDv1($data);

$this->assertSame($expectedCIDv1, $computedCIDv1);
}
}