Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added addWithWrap method. #4

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
}
],
"require": {
"php": ">=5.3.0",
"php": ">=5.5.0",
"ext-curl": "*"
},
"autoload": {
Expand Down
166 changes: 147 additions & 19 deletions src/IPFS.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

namespace Cloutier\PhpIpfsApi;

use Exception;

class IPFS {
private $gatewayIP;
private $gatewayPort;
Expand All @@ -24,14 +26,72 @@ public function cat ($hash) {

}

public function add ($content) {
/**
* Adds a file directly to IPFS
* @param string $filepath a filepath to upload
* @param boolean $pin pin the file (true)
* @return string The content hash
*/
public function add ($filepath, $pin=true) {
$ip = $this->gatewayIP;
$port = $this->gatewayApiPort;

$query_vars = [
'pin' => ($pin ? 'true' : 'false'),
];

$response = $this->postFile("/api/v0/add", $filepath, $query_vars);
return $response['Hash'];
}

/**
* Adds files to a folder in IPFS
*
* Returns data in the form of:
* {
* "files": [
* {
* "Name": "brown-square.png",
* "Hash": "Qmb3isYtDpPEAgEBCUBQMU8tqP23h2Rp99zZivWKUmuGMd"
* },
* {
* "Name": "brown-square.jpg",
* "Hash": "QmZc5W8EXWwRid2djYgG8w2MrDM7CyhHArozF5Ro8C5b8W"
* }
* ],
* "FolderHash": "QmWXmr7sxZHVQjMhY9tPgAuHYrXpxKTjW6MYfaTPVCLLgr"
* }
* @param multi $filepath_or_filepaths a single filepath or an array of filepaths to upload
* @param boolean $pin pin the file (true)
* @return array Data with Name, Hash and FolderHash
*/
public function addWithWrap ($filepath_or_filepaths, $pin=true) {
$ip = $this->gatewayIP;
$port = $this->gatewayApiPort;

$req = $this->curl("http://$ip:$port/api/v0/add?stream-channels=true", $content);
$req = json_decode($req, TRUE);
$query_vars = [
'pin' => ($pin ? 'true' : 'false'),
'w' => 'true',
];

$responses = $this->postFile("/api/v0/add", $filepath_or_filepaths, $query_vars, $expect_multiple = true);

$return_data = [
'files' => [],
'FolderHash' => '',
];

$responses_count = count($responses);
for ($i=0; $i < $responses_count; $i++) {
if ($i === $responses_count - 1) {
$return_data['FolderHash'] = $responses[$i]['Hash'];
continue;
}

$return_data['files'][$i] = $responses[$i];
}

return $req['Hash'];
return $return_data;
}

public function ls ($hash) {
Expand Down Expand Up @@ -66,35 +126,103 @@ public function pinAdd ($hash) {
return $data;
}

public function version () {

$ip = $this->gatewayIP;
$port = $this->gatewayApiPort;
$response = $this->curl("http://$ip:$port/api/v0/version");
$data = json_decode($response, TRUE);
return $data["Version"];
}
public function pinRemove ($hash) {

$ip = $this->gatewayIP;
$port = $this->gatewayApiPort;

private function curl ($url, $data = "") {
$response = $this->curl("http://$ip:$port/api/v0/pin/rm/$hash");
$data = json_decode($response, TRUE);

return $data;
}

public function version () {

$ip = $this->gatewayIP;
$port = $this->gatewayApiPort;
$response = $this->curl("http://$ip:$port/api/v0/version");
$data = json_decode($response, TRUE);
return $data["Version"];
}

public function get($api_path, $query_vars=[]) {
$ip = $this->gatewayIP;
$port = $this->gatewayApiPort;

$query_string = $query_vars ? '?'.http_build_query($query_vars) : '';
$response = $this->curl("http://{$ip}:{$port}/".ltrim($api_path,'/').$query_string);
$data = json_decode($response, true);
return $data;
}

public function postFile($api_path, $filepath, $query_vars=[], $expect_multiple=false) {
$ip = $this->gatewayIP;
$port = $this->gatewayApiPort;

$query_string = $query_vars ? '?'.http_build_query($query_vars) : '';
$response = $this->curl("http://{$ip}:{$port}/".ltrim($api_path,'/').$query_string, $filepath);

if ($expect_multiple) {
$data = [];
foreach (explode("\n", $response) as $json_data_line) {
if (strlen(trim($json_data_line))) {
$data[] = json_decode($json_data_line, true);
}
}
} else {
$data = json_decode($response, true);
}

return $data;
}

private function curl ($url, $filepath_or_filepaths=null) {
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_TIMEOUT, 240);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);

if ($data != "") {
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: multipart/form-data; boundary=a831rwxi1a3gzaorw1w2z49dlsor'));
if ($filepath_or_filepaths !== null) {
$filepaths = $filepath_or_filepaths;
if (!is_array($filepaths)) { $filepaths = [$filepath_or_filepaths]; }

$post_fields = [];
foreach($filepaths as $offset => $filepath) {
// add the file
$cfile = curl_file_create($filepath, 'application/octet-stream', basename($filepath));
$post_fields['file'.sprintf('%03d', $offset + 1)] = $cfile;
}

curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "--a831rwxi1a3gzaorw1w2z49dlsor\r\nContent-Type: application/octet-stream\r\nContent-Disposition: file; \r\n\r\n" . $data . " a831rwxi1a3gzaorw1w2z49dlsor");
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
}

$output = curl_exec($ch);

if ($output == FALSE) {
//todo: when ipfs doesn't answer
// check HTTP response code
$response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$code_category = substr($response_code, 0, 1);
if ($code_category == '5' OR $code_category == '4') {
$data = @json_decode($output, true);
if (!$data AND json_last_error() != JSON_ERROR_NONE) {
throw new Exception("IPFS returned response code $response_code: ".substr($output, 0, 200), $response_code);
}
if (is_array($data)) {
if (isset($data['Code']) AND isset($data['Message'])) {
throw new Exception("IPFS Error {$data['Code']}: {$data['Message']}", $response_code);
}
}
}

// handle empty response
if ($output === false) {
throw new Exception("IPFS Error: No Response", 1);
}

curl_close($ch);


Expand Down