Skip to content

Commit 24db355

Browse files
committed
feat: make engineId optional, use single /process/localize endpoint
1 parent 0533ab1 commit 24db355

File tree

4 files changed

+95
-53
lines changed

4 files changed

+95
-53
lines changed

README.md

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ composer require lingodotdev/sdk
1212

1313
## Basic Usage
1414

15-
After installing the package, bootstrap the engine with your API key and Engine ID:
15+
After installing the package, bootstrap the engine with your API key:
1616

1717
```php
1818
require 'vendor/autoload.php';
@@ -21,7 +21,7 @@ use LingoDotDev\Sdk\LingoDotDevEngine;
2121

2222
$engine = new LingoDotDevEngine([
2323
'apiKey' => 'your-api-key', // replace with your actual key
24-
'engineId' => 'your-engine-id', // replace with your actual engine id
24+
'engineId' => 'your-engine-id', // optional — override the default engine
2525
]);
2626
```
2727

@@ -30,7 +30,7 @@ $engine = new LingoDotDevEngine([
3030
| Option | Type | Required | Default | Description |
3131
|---|---|---|---|---|
3232
| `apiKey` | string | Yes || Your Lingo.dev API key |
33-
| `engineId` | string | Yes || Your Lingo.dev Engine ID |
33+
| `engineId` | string | No || Your Lingo.dev Engine ID |
3434
| `apiUrl` | string | No | `https://api.lingo.dev` | API base URL |
3535
| `batchSize` | int | No | `25` | Max items per chunk (1–250) |
3636
| `idealBatchItemSize` | int | No | `250` | Max words per chunk (1–2500) |
@@ -84,10 +84,10 @@ Follow these steps to create a new PHP project that uses the Lingo.dev SDK:
8484

8585
use LingoDotDev\Sdk\LingoDotDevEngine;
8686

87-
// Initialize the SDK with your API key and Engine ID
87+
// Initialize the SDK with your API key
8888
$engine = new LingoDotDevEngine([
8989
'apiKey' => 'your-api-key',
90-
'engineId' => 'your-engine-id',
90+
'engineId' => 'your-engine-id', // optional
9191
]);
9292
```
9393

@@ -104,17 +104,6 @@ $localizedText = $engine->localizeText('Hello, world!', [
104104
// Output: "¡Hola, mundo!"
105105
```
106106

107-
You can enable fast mode for quicker (but potentially lower quality) translations:
108-
109-
```php
110-
// Localize with fast mode enabled
111-
$localizedText = $engine->localizeText('Hello, world!', [
112-
'sourceLocale' => 'en',
113-
'targetLocale' => 'es',
114-
'fast' => true,
115-
]);
116-
```
117-
118107
### Object Localization
119108

120109
Translate an array of strings while preserving the structure:
@@ -228,13 +217,13 @@ $engine->localizeText('Hello, world!', [
228217

229218
## Demo App
230219

231-
If you prefer to start with a minimal example instead of the detailed scenarios above, create **index.php** in an empty folder, copy the following snippet, install dependencies with `composer require lingodotdev/sdk`, set `LINGODOTDEV_API_KEY` and `LINGODOTDEV_ENGINE_ID`, and run `php index.php`.
220+
If you prefer to start with a minimal example instead of the detailed scenarios above, create **index.php** in an empty folder, copy the following snippet, install dependencies with `composer require lingodotdev/sdk`, set `LINGODOTDEV_API_KEY` (and optionally `LINGODOTDEV_ENGINE_ID`), and run `php index.php`.
232221

233222
Want to see everything in action?
234223

235224
1. Clone this repository or copy the `index.php` from the **demo** below into an empty directory.
236225
2. Run `composer install` to pull in the SDK.
237-
3. Populate the `LINGODOTDEV_API_KEY` and `LINGODOTDEV_ENGINE_ID` environment variables.
226+
3. Populate the `LINGODOTDEV_API_KEY` environment variable (and optionally `LINGODOTDEV_ENGINE_ID`).
238227
4. Execute the script with `php index.php` and observe the output.
239228

240229
`index.php` demo:
@@ -246,10 +235,13 @@ require 'vendor/autoload.php';
246235

247236
use LingoDotDev\Sdk\LingoDotDevEngine;
248237

249-
$engine = new LingoDotDevEngine([
238+
$config = [
250239
'apiKey' => getenv('LINGODOTDEV_API_KEY'),
251-
'engineId' => getenv('LINGODOTDEV_ENGINE_ID'),
252-
]);
240+
];
241+
if (getenv('LINGODOTDEV_ENGINE_ID')) {
242+
$config['engineId'] = getenv('LINGODOTDEV_ENGINE_ID');
243+
}
244+
$engine = new LingoDotDevEngine($config);
253245

254246
// 1. Text
255247
$helloEs = $engine->localizeText('Hello world!', [

src/LingoDotDevEngine.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,6 @@ public function __construct(array $config = [])
6767
throw new \InvalidArgumentException('API key is required');
6868
}
6969

70-
if (empty($this->config['engineId'])) {
71-
throw new \InvalidArgumentException('Engine ID is required');
72-
}
73-
7470
if (!filter_var($this->config['apiUrl'], FILTER_VALIDATE_URL)) {
7571
throw new \InvalidArgumentException('API URL must be a valid URL');
7672
}
@@ -160,7 +156,7 @@ protected function localizeRaw(array $payload, array $params, ?callable $progres
160156
private function _localizeChunk(?string $sourceLocale, string $targetLocale, array $payload, bool $fast): array
161157
{
162158
try {
163-
$url = '/process/' . $this->config['engineId'] . '/localize';
159+
$url = '/process/localize';
164160
$requestBody = [
165161
'params' => ['fast' => $fast],
166162
'sourceLocale' => $sourceLocale,
@@ -169,6 +165,10 @@ private function _localizeChunk(?string $sourceLocale, string $targetLocale, arr
169165
'sessionId' => $this->_sessionId,
170166
];
171167

168+
if (!empty($this->config['engineId'])) {
169+
$requestBody['engineId'] = $this->config['engineId'];
170+
}
171+
172172
if (isset($payload['reference']) && $payload['reference'] !== null) {
173173
if (!is_array($payload['reference'])) {
174174
throw new \InvalidArgumentException('Reference must be an array');

test-all-methods.php

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* This script tests all available methods in the PHP SDK with real API calls
66
* to ensure they work correctly.
77
*
8-
* Usage: php test-all-methods.php <api_key> <engine_id>
8+
* Usage: php test-all-methods.php <api_key> [engine_id] [api_url]
99
*/
1010

1111
require "vendor/autoload.php";
@@ -15,16 +15,23 @@
1515

1616
$apiKey = $argv[1] ?? null;
1717
$engineId = $argv[2] ?? null;
18+
$apiUrl = $argv[3] ?? null;
1819

19-
if (!$apiKey || !$engineId) {
20-
echo "Usage: php test-all-methods.php <api_key> <engine_id>\n";
20+
if (!$apiKey) {
21+
echo "Usage: php test-all-methods.php <api_key> [engine_id] [api_url]\n";
2122
exit(1);
2223
}
2324

24-
$engine = new LingoDotDevEngine([
25+
$config = [
2526
"apiKey" => $apiKey,
26-
"engineId" => $engineId,
27-
]);
27+
];
28+
if ($engineId) {
29+
$config["engineId"] = $engineId;
30+
}
31+
if ($apiUrl) {
32+
$config["apiUrl"] = $apiUrl;
33+
}
34+
$engine = new LingoDotDevEngine($config);
2835

2936
$passed = 0;
3037
$failed = 0;
@@ -60,16 +67,7 @@ function runTest($name, $callback) {
6067
]);
6168
});
6269

63-
// 2. localizeText with fast mode
64-
runTest("localizeText (fast mode)", function() use ($engine) {
65-
return $engine->localizeText("The quick brown fox jumps over the lazy dog.", [
66-
"sourceLocale" => "en",
67-
"targetLocale" => "fr",
68-
"fast" => true,
69-
]);
70-
});
71-
72-
// 3. localizeObject
70+
// 2. localizeObject
7371
runTest("localizeObject", function() use ($engine) {
7472
return $engine->localizeObject([
7573
"greeting" => "Hello",
@@ -84,7 +82,7 @@ function runTest($name, $callback) {
8482
]);
8583
});
8684

87-
// 4. localizeChat
85+
// 3. localizeChat
8886
runTest("localizeChat", function() use ($engine) {
8987
return $engine->localizeChat([
9088
["name" => "Alice", "text" => "Hello, how are you?"],
@@ -96,20 +94,20 @@ function runTest($name, $callback) {
9694
]);
9795
});
9896

99-
// 5. batchLocalizeText
97+
// 4. batchLocalizeText
10098
runTest("batchLocalizeText", function() use ($engine) {
10199
return $engine->batchLocalizeText("Hello, world!", [
102100
"sourceLocale" => "en",
103101
"targetLocales" => ["es", "fr", "de"],
104102
]);
105103
});
106104

107-
// 6. recognizeLocale
105+
// 5. recognizeLocale
108106
runTest("recognizeLocale", function() use ($engine) {
109107
return $engine->recognizeLocale("Bonjour le monde");
110108
});
111109

112-
// 7. localizeObject with reference
110+
// 6. localizeObject with reference
113111
runTest("localizeObject with reference", function() use ($engine) {
114112
return $engine->localizeObject([
115113
"greeting" => "Hello",
@@ -126,7 +124,7 @@ function runTest($name, $callback) {
126124
]);
127125
});
128126

129-
// 8. Progress callback
127+
// 7. Progress callback
130128
runTest("Progress Callback", function() use ($engine) {
131129
$progressCalled = false;
132130
$progressValue = 0;

tests/LingoDotDevEngineTest.php

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,16 @@ public function testConstructorWithValidConfig()
114114
}
115115

116116
/**
117-
* Tests constructor requires engineId
117+
* Tests constructor works without engineId
118118
*
119119
* @return void
120120
*/
121-
public function testConstructorRequiresEngineId()
121+
public function testConstructorWithoutEngineId()
122122
{
123-
$this->expectException(\InvalidArgumentException::class);
124-
$this->expectExceptionMessage('Engine ID is required');
125-
new LingoDotDevEngine(['apiKey' => 'test-api-key']);
123+
$engine = new LingoDotDevEngine([
124+
'apiKey' => 'test-api-key',
125+
]);
126+
$this->assertInstanceOf(LingoDotDevEngine::class, $engine);
126127
}
127128

128129
/**
@@ -497,7 +498,8 @@ public function testLocalizeChunkUrlAndBody()
497498
$request = $history[0]['request'];
498499

499500
// Check URL
500-
$this->assertStringContainsString('/process/my-engine/localize', $request->getUri()->getPath());
501+
$this->assertStringContainsString('/process/localize', $request->getUri()->getPath());
502+
$this->assertStringNotContainsString('/process/my-engine/localize', $request->getUri()->getPath());
501503

502504
// Check body format
503505
$body = json_decode($request->getBody()->getContents(), true);
@@ -507,12 +509,62 @@ public function testLocalizeChunkUrlAndBody()
507509
$this->assertEquals(['text' => 'Hello'], $body['data']);
508510
$this->assertArrayHasKey('sessionId', $body);
509511
$this->assertNotEmpty($body['sessionId']);
512+
$this->assertEquals('my-engine', $body['engineId']);
510513

511514
// vNext should NOT have workflowId or locale object
512515
$this->assertArrayNotHasKey('workflowId', $body['params']);
513516
$this->assertArrayNotHasKey('locale', $body);
514517
}
515518

519+
/**
520+
* Tests localize chunk URL and body format without engineId
521+
*
522+
* @return void
523+
*/
524+
public function testLocalizeChunkUrlAndBodyWithoutEngineId()
525+
{
526+
$history = [];
527+
$mock = new MockHandler([
528+
new Response(200, [], json_encode(['data' => ['text' => 'Hola']]))
529+
]);
530+
$handlerStack = HandlerStack::create($mock);
531+
$handlerStack->push(\GuzzleHttp\Middleware::history($history));
532+
533+
$engine = new LingoDotDevEngine([
534+
'apiKey' => 'test-api-key',
535+
]);
536+
537+
$client = new Client([
538+
'handler' => $handlerStack,
539+
'headers' => [
540+
'Content-Type' => 'application/json; charset=utf-8',
541+
'X-API-Key' => 'test-api-key'
542+
]
543+
]);
544+
545+
$reflection = new ReflectionClass($engine);
546+
$property = $reflection->getProperty('_httpClient');
547+
$property->setAccessible(true);
548+
$property->setValue($engine, $client);
549+
550+
$engine->localizeText('Hello', [
551+
'sourceLocale' => 'en',
552+
'targetLocale' => 'es',
553+
]);
554+
555+
$this->assertCount(1, $history);
556+
$request = $history[0]['request'];
557+
558+
// Check URL is /process/localize
559+
$this->assertStringContainsString('/process/localize', $request->getUri()->getPath());
560+
561+
// Check body omits engineId
562+
$body = json_decode($request->getBody()->getContents(), true);
563+
$this->assertArrayNotHasKey('engineId', $body);
564+
$this->assertEquals('en', $body['sourceLocale']);
565+
$this->assertEquals('es', $body['targetLocale']);
566+
}
567+
516568
/**
517569
* Tests that sessionId is consistent across multiple requests
518570
*

0 commit comments

Comments
 (0)