Skip to content

Commit 6d83638

Browse files
committed
feat: v2.0.0 - complete SDK rewrite with PSR-7 streaming and PHPUnit tests
- Full rewrite: ConversionToolsClient, FilesApi, TasksApi, ConfigApi, Task model - HttpClient with Guzzle, retry logic, rate limit tracking, streaming support - PSR-7 StreamInterface via downloadStream() on FilesApi and Task - Validation, Polling, and Retry utilities - 9 exception classes (hierarchy under ConversionToolsException) - 111 PHPUnit tests across 7 test files - Require PHP >=8.1, guzzlehttp/guzzle ^7.0, phpunit/phpunit ^13.0 (dev) - Remove v1 files (API.php, ConversionClient.php, Request.php, autoload.php)
1 parent 43bca40 commit 6d83638

42 files changed

Lines changed: 3076 additions & 392 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
11
vendor/
2+
composer.lock
3+
.phpunit.cache/
4+
.phpunit.result.cache
5+
*.log

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2020 Conversion Tools
3+
Copyright (c) 2026 Conversion Tools
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 145 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,123 +1,198 @@
1-
# [Conversion Tools](https://conversiontools.io) API PHP Client
1+
# [Conversion Tools](https://conversiontools.io) PHP Client
22

3-
[Conversion Tools](https://conversiontools.io) is an online service that offers a fast and easy way to convert documents between different formats, like XML, Excel, PDF, Word, Text, CSV and others.
3+
[Conversion Tools](https://conversiontools.io) is an online service for converting files between formats XML, Excel, PDF, Word, CSV, JSON, images, audio, video, and more.
44

5-
This client allows to integrate the conversion of the files into PHP applications.
5+
This library integrates file conversion into PHP applications via the [Conversion Tools REST API](https://conversiontools.io/api-documentation).
66

7-
To convert the files PHP Client uses the public [Conversion Tools REST API](https://conversiontools.io/api-documentation).
7+
## Requirements
88

9-
## Installation
9+
- PHP 8.1 or later
10+
- ext-curl, ext-json (enabled by default in standard PHP installs)
1011

11-
### Installation using Composer
12+
## Installation
1213

1314
```bash
1415
composer require conversiontools/conversiontools-php
1516
```
1617

17-
or without composer:
18+
## Quick Start
1819

19-
```php
20-
require_once('conversiontools-php/src/autoload.php');
21-
```
22-
23-
## Examples
24-
25-
To use REST API - get API Token from the Profile page at https://conversiontools.io/profile.
26-
27-
### Converting file
28-
29-
See example `convert-file.php` in the `./examples/` folder.
20+
Get your API token from [conversiontools.io/profile](https://conversiontools.io/profile).
3021

3122
```php
3223
<?php
3324

3425
require_once __DIR__ . '/vendor/autoload.php';
3526

36-
use \ConversionTools\ConversionClient;
27+
use ConversionTools\ConversionToolsClient;
28+
29+
$client = new ConversionToolsClient([
30+
'api_token' => 'your-api-token',
31+
]);
3732

38-
// put token here from your Profile page at https://conversiontools.io/profile
39-
$token = '';
33+
$client->convert('convert.pdf_to_word', 'input.pdf', 'output.docx');
34+
```
4035

41-
$fileOrUrlInput = 'test.xml';
42-
$fileOutput = 'test.csv';
36+
## Examples
4337

44-
$options = ['delimiter' => 'tabulation'];
38+
### Convert a file
4539

46-
$client = new ConversionClient($token);
47-
try {
48-
$client->convert('convert.xml_to_csv', $fileOrUrlInput, $fileOutput, $options);
49-
} catch (Exception $e) {
50-
print 'Exception: ' . $e->getMessage() . "\n";
51-
}
40+
```php
41+
$client->convert('convert.xml_to_csv', 'data.xml', 'data.csv', [
42+
'delimiter' => 'tabulation',
43+
]);
5244
```
5345

54-
### Converting URL
46+
### Convert a URL
5547

56-
See example `convert-url.php` in the `./examples/` folder.
48+
```php
49+
$client->convert('convert.website_to_pdf', ['url' => 'https://example.com'], 'result.pdf');
50+
```
51+
52+
### Use a pre-uploaded file
5753

5854
```php
59-
<?php
55+
$fileId = $client->files->upload('input.pdf');
6056

61-
require_once __DIR__ . '/vendor/autoload.php';
57+
$client->convert('convert.pdf_to_word', ['file_id' => $fileId], 'output.docx');
58+
```
6259

63-
use \ConversionTools\ConversionClient;
60+
### Manual control (upload → task → wait → download)
6461

65-
// put token here from your Profile page at https://conversiontools.io/profile
66-
$token = '';
62+
```php
63+
$fileId = $client->files->upload('input.pdf');
6764

68-
$fileOrUrlInput = 'https://google.com';
69-
$fileOutput = 'result.pdf';
65+
$task = $client->createTask('convert.pdf_to_word', ['file_id' => $fileId]);
7066

71-
$options = [];
67+
$task->wait([
68+
'on_progress' => function (array $status): void {
69+
echo "{$status['conversionProgress']}% [{$status['status']}]\n";
70+
},
71+
]);
7272

73-
$client = new ConversionClient($token);
74-
try {
75-
$client->convert('convert.website_to_pdf', $fileOrUrlInput, $fileOutput, $options);
76-
} catch (Exception $e) {
77-
print 'Exception: ' . $e->getMessage() . "\n";
78-
}
73+
$task->downloadTo('output.docx');
7974
```
8075

81-
## API
76+
### Fire and forget (webhook)
8277

83-
### Create `ConversionClient` instance with a token.
8478
```php
85-
use \ConversionTools\ConversionClient;
86-
87-
$client = new ConversionClient('<token>');
79+
$taskId = $client->convert(
80+
conversionType: 'convert.pdf_to_word',
81+
input: 'input.pdf',
82+
wait: false,
83+
callbackUrl: 'https://your-app.com/webhook',
84+
);
8885
```
8986

90-
Where `<token>` is API token from the account's Profile page https://conversiontools.io/profile.
87+
### Error handling
9188

92-
### Convert input file and download the result
9389
```php
94-
$client = new ConversionClient($token);
90+
use ConversionTools\Exceptions\ConversionToolsException;
91+
use ConversionTools\Exceptions\RateLimitException;
92+
use ConversionTools\Exceptions\ConversionException;
93+
9594
try {
96-
$client->convert('<conversion type>', $fileOrUrlInput, $fileOutput, $options);
97-
} catch (Exception $e) {
98-
print 'Exception: ' . $e->getMessage() . "\n";
95+
$client->convert('convert.pdf_to_word', 'input.pdf', 'output.docx');
96+
} catch (RateLimitException $e) {
97+
echo "Quota exceeded. Daily remaining: {$e->limits['daily']['remaining']}\n";
98+
} catch (ConversionException $e) {
99+
echo "Conversion failed for task {$e->taskId}: {$e->taskError}\n";
100+
} catch (ConversionToolsException $e) {
101+
echo "Error [{$e->errorCode}]: {$e->getMessage()}\n";
99102
}
100103
```
101104

102-
Where
103-
- `<conversion type>` is a specific type of conversion, from [API Documentation](https://conversiontools.io/api-documentation).
104-
- `$fileOrUrlInput` is the filename of the input file, or URL of the file to convert (when applicable)
105-
- `$fileOutput` is the filename of the output file
106-
- `$options` is a PHP array with options for a corresponding converter, for example:
105+
## API
106+
107+
### `new ConversionToolsClient(array $config)`
108+
109+
| Key | Type | Default | Description |
110+
|---|---|---|---|
111+
| `api_token` | string | **required** | API token from your profile |
112+
| `base_url` | string | `https://api.conversiontools.io/v1` | API base URL |
113+
| `timeout` | float (ms) | `300000` | Request timeout |
114+
| `retries` | int | `3` | Retry attempts on transient errors |
115+
| `retry_delay` | float (ms) | `1000` | Initial retry delay (doubles each attempt) |
116+
| `polling_interval` | float (ms) | `5000` | How often to poll task status |
117+
| `max_polling_interval` | float (ms) | `30000` | Max polling interval (with backoff) |
118+
| `polling_backoff` | float | `1.5` | Polling backoff multiplier |
119+
| `webhook_url` | string | `null` | Default webhook URL for all tasks |
120+
| `on_conversion_progress` | callable | `null` | Called on each poll with progress info |
121+
122+
### `convert(string $conversionType, string|array $input, ?string $output, array $options, bool $wait, ?string $callbackUrl): string`
123+
124+
One-call conversion. Returns the output file path (if `$wait=true`) or task ID (if `$wait=false`).
125+
126+
**Input formats:**
127+
- `'path/to/file.pdf'` — local file path
128+
- `['url' => 'https://...']` — URL-based conversion
129+
- `['file_id' => '...']` — pre-uploaded file
130+
131+
### `createTask(string $conversionType, array $options, ?string $callbackUrl): Task`
132+
133+
Create a task without waiting. Returns a `Task` object.
134+
135+
### `getTask(string $taskId): Task`
136+
137+
Retrieve an existing task by ID.
138+
139+
### `getRateLimits(): ?array`
140+
141+
Returns rate limit info from the last API response.
142+
107143
```php
108-
$options = ['delimiter' => 'tabulation'];
144+
$limits = $client->getRateLimits();
145+
// ['daily' => ['limit' => 30, 'remaining' => 25], 'monthly' => [...]]
109146
```
110147

111-
## Requirements
112-
113-
PHP version 5.4.0 or later.
148+
### `Task`
149+
150+
| Method | Description |
151+
|---|---|
152+
| `wait(array $options = [])` | Poll until complete. Accepts `polling_interval`, `max_polling_interval`, `timeout`, `on_progress` |
153+
| `downloadTo(?string $path)` | Download result to file, returns resolved path |
154+
| `downloadBytes()` | Download result as string |
155+
| `refresh()` | Re-fetch status from API |
156+
| `getStatus()` | Returns current status string |
157+
| `isSuccess()` / `isError()` / `isRunning()` / `isComplete()` | Status helpers |
158+
| `toArray()` | Serialize task state |
159+
160+
### `$client->files`
161+
162+
| Method | Description |
163+
|---|---|
164+
| `upload(string $filePath): string` | Upload file, returns `file_id` |
165+
| `getInfo(string $fileId): array` | Get file metadata |
166+
| `downloadBytes(string $fileId): string` | Download as string |
167+
| `downloadTo(string $fileId, ?string $outputPath): string` | Download to file |
168+
169+
### `$client->tasks`
170+
171+
| Method | Description |
172+
|---|---|
173+
| `create(array $request): array` | Create task (low-level) |
174+
| `getStatus(string $taskId): array` | Get task status |
175+
| `list(?string $status): array` | List tasks, optionally filtered by status |
176+
177+
### Exceptions
178+
179+
All exceptions extend `ConversionToolsException` and expose `$errorCode` and `$httpStatus`.
180+
181+
| Exception | Trigger |
182+
|---|---|
183+
| `AuthenticationException` | Invalid or missing API token |
184+
| `ValidationException` | Bad request parameters |
185+
| `RateLimitException` | Quota exceeded — has `$limits` property |
186+
| `FileNotFoundException` | File ID not found |
187+
| `TaskNotFoundException` | Task ID not found |
188+
| `ConversionException` | Task failed — has `$taskId` and `$taskError` |
189+
| `TimeoutException` | Request or polling timed out |
190+
| `NetworkException` | Connection error |
114191

115192
## Documentation
116193

117-
List of available Conversion Types and corresponding conversion options can be found on the [Conversion Tools API Documentation](https://conversiontools.io/api-documentation) page.
194+
Full list of conversion types and options: [conversiontools.io/api-documentation](https://conversiontools.io/api-documentation)
118195

119196
## License
120197

121-
Licensed under [MIT](./LICENSE).
122-
123-
Copyright (c) 2021 [Conversion Tools](https://conversiontools.io)
198+
Licensed under [MIT](./LICENSE). Copyright (c) [Conversion Tools](https://conversiontools.io)

composer.json

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,30 @@
22
"name": "conversiontools/conversiontools-php",
33
"type": "library",
44
"description": "Conversion Tools REST API PHP Client library",
5-
"keywords": ["convert","conversion","conversiontools","convert files","client","api","sdk"],
5+
"keywords": ["convert", "conversion", "conversiontools", "convert files", "client", "api", "sdk"],
66
"homepage": "https://github.com/conversiontools/conversiontools-php",
77
"license": "MIT",
8+
"version": "2.0.0",
89
"require": {
9-
"ext-curl": "*",
10-
"ext-json": "*",
11-
"php": ">=5.4.0"
10+
"php": ">=8.1",
11+
"guzzlehttp/guzzle": "^7.0"
1212
},
13-
"config": {
14-
"bin-dir": "bin"
13+
"require-dev": {
14+
"phpunit/phpunit": "^13.0"
1515
},
1616
"autoload": {
1717
"psr-4": {
1818
"ConversionTools\\": "src/"
1919
}
2020
},
21+
"autoload-dev": {
22+
"psr-4": {
23+
"ConversionTools\\Tests\\": "tests/"
24+
}
25+
},
26+
"config": {
27+
"sort-packages": true
28+
},
2129
"authors": [
2230
{
2331
"name": "Conversion Tools",

composer.lock

Lines changed: 0 additions & 21 deletions
This file was deleted.

examples/convert-file.php

Lines changed: 0 additions & 20 deletions
This file was deleted.

examples/convert-json-to-csv.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
require_once __DIR__ . '/../vendor/autoload.php';
6+
7+
use ConversionTools\ConversionToolsClient;
8+
use ConversionTools\Exceptions\ConversionToolsException;
9+
10+
// Get your API token from https://conversiontools.io/profile
11+
$token = getenv('CT_API_TOKEN') ?: 'your-api-token-here';
12+
13+
$client = new ConversionToolsClient([
14+
'api_token' => $token,
15+
]);
16+
17+
try {
18+
$outputPath = $client->convert(
19+
conversionType: 'convert.json_to_csv',
20+
input: __DIR__ . '/test.json',
21+
output: __DIR__ . '/test.csv',
22+
);
23+
24+
echo "Done! Saved to: {$outputPath}\n";
25+
} catch (ConversionToolsException $e) {
26+
echo "Error [{$e->errorCode}]: {$e->getMessage()}\n";
27+
}

0 commit comments

Comments
 (0)