From 7fbb8340fd0ea207f9e37b961b2fc1bfa2292c99 Mon Sep 17 00:00:00 2001 From: Paul DelRe Date: Wed, 1 Oct 2025 14:19:41 -0400 Subject: [PATCH 1/6] add `TranslationMemorySegmentRecord` --- .../Model/TranslationMemorySegmentRecord.php | 190 ++++++++++++++++++ .../TranslationMemorySegmentRecordTest.php | 68 +++++++ 2 files changed, 258 insertions(+) create mode 100644 src/CrowdinApiClient/Model/TranslationMemorySegmentRecord.php create mode 100644 tests/CrowdinApiClient/Model/TranslationMemorySegmentRecordTest.php diff --git a/src/CrowdinApiClient/Model/TranslationMemorySegmentRecord.php b/src/CrowdinApiClient/Model/TranslationMemorySegmentRecord.php new file mode 100644 index 00000000..a0def1d3 --- /dev/null +++ b/src/CrowdinApiClient/Model/TranslationMemorySegmentRecord.php @@ -0,0 +1,190 @@ +id = (integer)$this->getDataProperty('id'); + $this->languageId = (string)$this->getDataProperty('languageId'); + $this->text = (string)$this->getDataProperty('text'); + $this->usageCount = (integer)$this->getDataProperty('usageCount'); + $this->createdBy = (integer)$this->getDataProperty('createdBy'); + $this->updatedBy = (integer)$this->getDataProperty('updatedBy'); + $this->createdAt = (string)$this->getDataProperty('createdAt'); + $this->updatedAt = (string)$this->getDataProperty('updatedAt'); + } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } + + /** + * @param int $id + */ + public function setId(int $id): void + { + $this->id = $id; + } + + /** + * @return string + */ + public function getLanguageId(): string + { + return $this->languageId; + } + + /** + * @param string $languageId + */ + public function setLanguageId(string $languageId): void + { + $this->languageId = $languageId; + } + + /** + * @return string + */ + public function getText(): string + { + return $this->text; + } + + /** + * @param string $text + */ + public function setText(string $text): void + { + $this->text = $text; + } + + /** + * @return int + */ + public function getUsageCount(): int + { + return $this->usageCount; + } + + /** + * @param int $usageCount + */ + public function setUsageCount(int $usageCount): void + { + $this->usageCount = $usageCount; + } + + /** + * @return int + */ + public function getCreatedBy(): int + { + return $this->createdBy; + } + + /** + * @param int $createdBy + */ + public function setCreatedBy(int $createdBy): void + { + $this->createdBy = $createdBy; + } + + /** + * @return int + */ + public function getUpdatedBy(): int + { + return $this->updatedBy; + } + + /** + * @param int $updatedBy + */ + public function setUpdatedBy(int $updatedBy): void + { + $this->updatedBy = $updatedBy; + } + + /** + * @return string|null + */ + public function getCreatedAt(): ?string + { + return $this->createdAt; + } + + /** + * @param string|null $createdAt + */ + public function setCreatedAt(?string $createdAt): void + { + $this->createdAt = $createdAt; + } + + /** + * @return string|null + */ + public function getUpdatedAt(): ?string + { + return $this->updatedAt; + } + + /** + * @param string|null $updatedAt + */ + public function setUpdatedAt(?string $updatedAt): void + { + $this->updatedAt = $updatedAt; + } +} diff --git a/tests/CrowdinApiClient/Model/TranslationMemorySegmentRecordTest.php b/tests/CrowdinApiClient/Model/TranslationMemorySegmentRecordTest.php new file mode 100644 index 00000000..965bb976 --- /dev/null +++ b/tests/CrowdinApiClient/Model/TranslationMemorySegmentRecordTest.php @@ -0,0 +1,68 @@ + 1, + 'languageId' => 'uk', + 'text' => 'Перекладений текст', + 'usageCount' => 13, + 'createdBy' => 1, + 'updatedBy' => 1, + 'createdAt' => '2019-09-16T13:48:04+00:00', + 'updatedAt' => '2019-09-16T13:48:04+00:00', + ]; + + public function testLoadData() + { + $this->record = new TranslationMemorySegmentRecord($this->data); + $this->checkData(); + } + + public function testSetData() + { + $this->record = new TranslationMemorySegmentRecord(); + $this->record->setId($this->data['id']); + $this->record->setLanguageId($this->data['languageId']); + $this->record->setText($this->data['text']); + $this->record->setUsageCount($this->data['usageCount']); + $this->record->setCreatedBy($this->data['createdBy']); + $this->record->setUpdatedBy($this->data['updatedBy']); + $this->record->setCreatedAt($this->data['createdAt']); + $this->record->setUpdatedAt($this->data['updatedAt']); + + $this->assertEquals($this->data['id'], $this->record->getId()); + $this->assertEquals($this->data['languageId'], $this->record->getLanguageId()); + $this->assertEquals($this->data['text'], $this->record->getText()); + $this->assertEquals($this->data['usageCount'], $this->record->getUsageCount()); + $this->assertEquals($this->data['createdBy'], $this->record->getCreatedBy()); + $this->assertEquals($this->data['updatedBy'], $this->record->getUpdatedBy()); + $this->assertEquals($this->data['createdAt'], $this->record->getCreatedAt()); + $this->assertEquals($this->data['updatedAt'], $this->record->getUpdatedAt()); + } + + public function checkData() + { + $this->assertEquals($this->data['id'], $this->record->getId()); + $this->assertEquals($this->data['languageId'], $this->record->getLanguageId()); + $this->assertEquals($this->data['text'], $this->record->getText()); + $this->assertEquals($this->data['usageCount'], $this->record->getUsageCount()); + $this->assertEquals($this->data['createdBy'], $this->record->getCreatedBy()); + $this->assertEquals($this->data['updatedBy'], $this->record->getUpdatedBy()); + $this->assertEquals($this->data['createdAt'], $this->record->getCreatedAt()); + $this->assertEquals($this->data['updatedAt'], $this->record->getUpdatedAt()); + } +} From ac4463b667ee6993403ce58fec41efdb7c0cc7e1 Mon Sep 17 00:00:00 2001 From: Paul DelRe Date: Wed, 1 Oct 2025 14:25:19 -0400 Subject: [PATCH 2/6] add `TranslationMemorySegment` --- .../Model/TranslationMemorySegment.php | 61 ++++++++++++++++ .../Model/TranslationMemorySegmentTest.php | 69 +++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 src/CrowdinApiClient/Model/TranslationMemorySegment.php create mode 100644 tests/CrowdinApiClient/Model/TranslationMemorySegmentTest.php diff --git a/src/CrowdinApiClient/Model/TranslationMemorySegment.php b/src/CrowdinApiClient/Model/TranslationMemorySegment.php new file mode 100644 index 00000000..30f2a7f2 --- /dev/null +++ b/src/CrowdinApiClient/Model/TranslationMemorySegment.php @@ -0,0 +1,61 @@ +id = (integer)$this->getDataProperty('id'); + $this->records = array_map(static function (array $record): TranslationMemorySegmentRecord { + return new TranslationMemorySegmentRecord($record); + }, (array)$this->getDataProperty('records')); + } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } + + /** + * @param int $id + */ + public function setId(int $id): void + { + $this->id = $id; + } + + /** + * @return TranslationMemorySegmentRecord[] + */ + public function getRecords(): array + { + return $this->records; + } + + /** + * @param TranslationMemorySegmentRecord[] $records + */ + public function setRecords(array $records): void + { + $this->records = $records; + } +} diff --git a/tests/CrowdinApiClient/Model/TranslationMemorySegmentTest.php b/tests/CrowdinApiClient/Model/TranslationMemorySegmentTest.php new file mode 100644 index 00000000..3cf39a4e --- /dev/null +++ b/tests/CrowdinApiClient/Model/TranslationMemorySegmentTest.php @@ -0,0 +1,69 @@ + 4, + 'records' => [ + [ + 'id' => 1, + 'languageId' => 'uk', + 'text' => 'Перекладений текст', + 'usageCount' => 13, + 'createdBy' => 1, + 'updatedBy' => 1, + 'createdAt' => '2019-09-16T13:48:04+00:00', + 'updatedAt' => '2019-09-16T13:48:04+00:00', + ], + ], + ]; + + public function testLoadData() + { + $this->segment = new TranslationMemorySegment($this->data); + $this->checkData(); + } + + public function testSetData() + { + $this->segment = new TranslationMemorySegment(); + $this->segment->setId($this->data['id']); + + $record = new TranslationMemorySegmentRecord($this->data['records'][0]); + $this->segment->setRecords([$record]); + + $this->assertEquals($this->data['id'], $this->segment->getId()); + $this->assertIsArray($this->segment->getRecords()); + $this->assertInstanceOf(TranslationMemorySegmentRecord::class, $this->segment->getRecords()[0]); + $this->assertEquals($this->data['records'][0]['id'], $this->segment->getRecords()[0]->getId()); + } + + public function checkData() + { + $this->assertEquals($this->data['id'], $this->segment->getId()); + $this->assertIsArray($this->segment->getRecords()); + $this->assertInstanceOf(TranslationMemorySegmentRecord::class, $this->segment->getRecords()[0]); + $this->assertEquals($this->data['records'][0]['id'], $this->segment->getRecords()[0]->getId()); + $this->assertEquals($this->data['records'][0]['languageId'], $this->segment->getRecords()[0]->getLanguageId()); + $this->assertEquals($this->data['records'][0]['text'], $this->segment->getRecords()[0]->getText()); + $this->assertEquals($this->data['records'][0]['usageCount'], $this->segment->getRecords()[0]->getUsageCount()); + $this->assertEquals($this->data['records'][0]['createdBy'], $this->segment->getRecords()[0]->getCreatedBy()); + $this->assertEquals($this->data['records'][0]['updatedBy'], $this->segment->getRecords()[0]->getUpdatedBy()); + $this->assertEquals($this->data['records'][0]['createdAt'], $this->segment->getRecords()[0]->getCreatedAt()); + $this->assertEquals($this->data['records'][0]['updatedAt'], $this->segment->getRecords()[0]->getUpdatedAt()); + } +} From 0c3d4014e88e9bcd43b1e760362ea4c091dd2feb Mon Sep 17 00:00:00 2001 From: Paul DelRe Date: Wed, 1 Oct 2025 16:31:04 -0400 Subject: [PATCH 3/6] add `TranslationMemoryApi::listSegments` # Conflicts: # tests/CrowdinApiClient/Api/TranslationMemoryApiTest.php --- .../Api/TranslationMemoryApi.php | 20 ++++++++++ .../Api/TranslationMemoryApiTest.php | 40 +++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/src/CrowdinApiClient/Api/TranslationMemoryApi.php b/src/CrowdinApiClient/Api/TranslationMemoryApi.php index 72a5ce15..6dbb8be8 100644 --- a/src/CrowdinApiClient/Api/TranslationMemoryApi.php +++ b/src/CrowdinApiClient/Api/TranslationMemoryApi.php @@ -8,6 +8,7 @@ use CrowdinApiClient\Model\TranslationMemoryConcordance; use CrowdinApiClient\Model\TranslationMemoryExport; use CrowdinApiClient\Model\TranslationMemoryImport; +use CrowdinApiClient\Model\TranslationMemorySegment; use CrowdinApiClient\ModelCollection; /** @@ -96,6 +97,25 @@ public function clear(int $translationMemoryId) return $this->_delete($path); } + /** + * List TM Segments + * @link https://developer.crowdin.com/api/v2/#operation/api.tms.segments.getMany API Documentation + * @link https://developer.crowdin.com/enterprise/api/v2/#operation/api.tms.segments.getMany API Documentation Enterprise + * + * @param int $tmId + * @param array $params + * string $params[orderBy]
+ * string $params[croql]
+ * integer $params[limit]
+ * integer $params[offset] + * @return ModelCollection + */ + public function listSegments(int $tmId, array $params = []): ModelCollection + { + $path = sprintf('tms/%d/segments', $tmId); + return $this->_list($path, TranslationMemorySegment::class, $params); + } + /** * Export TM * @link https://developer.crowdin.com/api/v2/#operation/api.tms.exports.post API Documentation diff --git a/tests/CrowdinApiClient/Api/TranslationMemoryApiTest.php b/tests/CrowdinApiClient/Api/TranslationMemoryApiTest.php index 25078d20..285a63c3 100644 --- a/tests/CrowdinApiClient/Api/TranslationMemoryApiTest.php +++ b/tests/CrowdinApiClient/Api/TranslationMemoryApiTest.php @@ -7,6 +7,7 @@ use CrowdinApiClient\Model\TranslationMemoryConcordance; use CrowdinApiClient\Model\TranslationMemoryExport; use CrowdinApiClient\Model\TranslationMemoryImport; +use CrowdinApiClient\Model\TranslationMemorySegment; use CrowdinApiClient\ModelCollection; class TranslationMemoryApiTest extends AbstractTestApi @@ -352,4 +353,43 @@ public function testConcordance(): void $this->assertInstanceOf(TranslationMemoryConcordance::class, $concordance[0]); $this->assertEquals(4, $concordance[0]->getTm()->getId()); } + + public function testListSegments() + { + $this->mockRequest([ + 'path' => '/tms/4/segments', + 'method' => 'get', + 'response' => '{ + "data": [ + { + "data": { + "id": 4, + "records": [ + { + "id": 1, + "languageId": "uk", + "text": "Перекладений текст", + "usageCount": 13, + "createdBy": 1, + "updatedBy": 1, + "createdAt": "2019-09-16T13:48:04+00:00", + "updatedAt": "2019-09-16T13:48:04+00:00" + } + ] + } + } + ], + "pagination": { + "offset": 0, + "limit": 25 + } + }' + ]); + + $segments = $this->crowdin->translationMemory->listSegments(4); + $this->assertInstanceOf(ModelCollection::class, $segments); + $this->assertCount(1, $segments); + $this->assertInstanceOf(TranslationMemorySegment::class, $segments[0]); + $this->assertEquals(4, $segments[0]->getId()); + } } From e023200064a1662070010d948491afee1ef4111d Mon Sep 17 00:00:00 2001 From: Paul DelRe Date: Wed, 1 Oct 2025 16:35:24 -0400 Subject: [PATCH 4/6] add `TranslationMemoryApi::getSegment` --- .../Api/TranslationMemoryApi.php | 15 +++++++++++ .../Api/TranslationMemoryApiTest.php | 25 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/CrowdinApiClient/Api/TranslationMemoryApi.php b/src/CrowdinApiClient/Api/TranslationMemoryApi.php index 6dbb8be8..3126c472 100644 --- a/src/CrowdinApiClient/Api/TranslationMemoryApi.php +++ b/src/CrowdinApiClient/Api/TranslationMemoryApi.php @@ -116,6 +116,21 @@ public function listSegments(int $tmId, array $params = []): ModelCollection return $this->_list($path, TranslationMemorySegment::class, $params); } + /** + * Get TM Segment + * @link https://developer.crowdin.com/api/v2/#operation/api.tms.segments.get API Documentation + * @link https://developer.crowdin.com/enterprise/api/v2/#operation/api.tms.segments.get API Documentation Enterprise + * + * @param int $tmId + * @param int $segmentId + * @return TranslationMemorySegment|null + */ + public function getSegment(int $tmId, int $segmentId): ?TranslationMemorySegment + { + $path = sprintf('tms/%d/segments/%d', $tmId, $segmentId); + return $this->_get($path, TranslationMemorySegment::class); + } + /** * Export TM * @link https://developer.crowdin.com/api/v2/#operation/api.tms.exports.post API Documentation diff --git a/tests/CrowdinApiClient/Api/TranslationMemoryApiTest.php b/tests/CrowdinApiClient/Api/TranslationMemoryApiTest.php index 285a63c3..c36a402c 100644 --- a/tests/CrowdinApiClient/Api/TranslationMemoryApiTest.php +++ b/tests/CrowdinApiClient/Api/TranslationMemoryApiTest.php @@ -392,4 +392,29 @@ public function testListSegments() $this->assertInstanceOf(TranslationMemorySegment::class, $segments[0]); $this->assertEquals(4, $segments[0]->getId()); } + + public function testGetSegment() + { + $this->mockRequestGet('/tms/4/segments/1', '{ + "data": { + "id": 4, + "records": [ + { + "id": 1, + "languageId": "uk", + "text": "Перекладений текст", + "usageCount": 13, + "createdBy": 1, + "updatedBy": 1, + "createdAt": "2019-09-16T13:48:04+00:00", + "updatedAt": "2019-09-16T13:48:04+00:00" + } + ] + } + }'); + + $segment = $this->crowdin->translationMemory->getSegment(4, 1); + $this->assertInstanceOf(TranslationMemorySegment::class, $segment); + $this->assertEquals(4, $segment->getId()); + } } From 34a810ac6463fd3dbee55026691cfd65bf9c0bee Mon Sep 17 00:00:00 2001 From: Paul DelRe Date: Wed, 1 Oct 2025 16:40:52 -0400 Subject: [PATCH 5/6] add `TranslationMemoryApi::createSegment` --- .../Api/TranslationMemoryApi.php | 18 +++++++++ .../Api/TranslationMemoryApiTest.php | 39 +++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/CrowdinApiClient/Api/TranslationMemoryApi.php b/src/CrowdinApiClient/Api/TranslationMemoryApi.php index 3126c472..78e0981a 100644 --- a/src/CrowdinApiClient/Api/TranslationMemoryApi.php +++ b/src/CrowdinApiClient/Api/TranslationMemoryApi.php @@ -131,6 +131,24 @@ public function getSegment(int $tmId, int $segmentId): ?TranslationMemorySegment return $this->_get($path, TranslationMemorySegment::class); } + /** + * Create TM Segment + * @link https://developer.crowdin.com/api/v2/#operation/api.tms.segments.post API Documentation + * @link https://developer.crowdin.com/enterprise/api/v2/#operation/api.tms.segments.post API Documentation Enterprise + * + * @param int $tmId + * @param array $data + * array $data[records]
+ * string $data[records][][languageId]
+ * string $data[records][][text] + * @return TranslationMemorySegment|null + */ + public function createSegment(int $tmId, array $data): ?TranslationMemorySegment + { + $path = sprintf('tms/%d/segments', $tmId); + return $this->_create($path, TranslationMemorySegment::class, $data); + } + /** * Export TM * @link https://developer.crowdin.com/api/v2/#operation/api.tms.exports.post API Documentation diff --git a/tests/CrowdinApiClient/Api/TranslationMemoryApiTest.php b/tests/CrowdinApiClient/Api/TranslationMemoryApiTest.php index c36a402c..80fddb0d 100644 --- a/tests/CrowdinApiClient/Api/TranslationMemoryApiTest.php +++ b/tests/CrowdinApiClient/Api/TranslationMemoryApiTest.php @@ -417,4 +417,43 @@ public function testGetSegment() $this->assertInstanceOf(TranslationMemorySegment::class, $segment); $this->assertEquals(4, $segment->getId()); } + + public function testCreateSegment() + { + $params = [ + 'records' => [ + [ + 'languageId' => 'uk', + 'text' => 'Перекладений текст', + ], + ], + ]; + + $this->mockRequest([ + 'path' => '/tms/4/segments', + 'method' => 'post', + 'body' => json_encode($params), + 'response' => '{ + "data": { + "id": 4, + "records": [ + { + "id": 1, + "languageId": "uk", + "text": "Перекладений текст", + "usageCount": 13, + "createdBy": 1, + "updatedBy": 1, + "createdAt": "2019-09-16T13:48:04+00:00", + "updatedAt": "2019-09-16T13:48:04+00:00" + } + ] + } + }' + ]); + + $segment = $this->crowdin->translationMemory->createSegment(4, $params); + $this->assertInstanceOf(TranslationMemorySegment::class, $segment); + $this->assertEquals(4, $segment->getId()); + } } From b0b411e0f035a476498f34aafc2d1ce494362058 Mon Sep 17 00:00:00 2001 From: Paul DelRe Date: Wed, 1 Oct 2025 16:44:33 -0400 Subject: [PATCH 6/6] add `TranslationMemoryApi::deleteSegment` --- src/CrowdinApiClient/Api/TranslationMemoryApi.php | 15 +++++++++++++++ .../Api/TranslationMemoryApiTest.php | 6 ++++++ 2 files changed, 21 insertions(+) diff --git a/src/CrowdinApiClient/Api/TranslationMemoryApi.php b/src/CrowdinApiClient/Api/TranslationMemoryApi.php index 78e0981a..47755a2a 100644 --- a/src/CrowdinApiClient/Api/TranslationMemoryApi.php +++ b/src/CrowdinApiClient/Api/TranslationMemoryApi.php @@ -149,6 +149,21 @@ public function createSegment(int $tmId, array $data): ?TranslationMemorySegment return $this->_create($path, TranslationMemorySegment::class, $data); } + /** + * Delete TM Segment + * @link https://developer.crowdin.com/api/v2/#operation/api.tms.segments.delete API Documentation + * @link https://developer.crowdin.com/enterprise/api/v2/#operation/api.tms.segments.delete API Documentation Enterprise + * + * @param int $tmId + * @param int $segmentId + * @return null + */ + public function deleteSegment(int $tmId, int $segmentId) + { + $path = sprintf('tms/%d/segments/%d', $tmId, $segmentId); + return $this->_delete($path); + } + /** * Export TM * @link https://developer.crowdin.com/api/v2/#operation/api.tms.exports.post API Documentation diff --git a/tests/CrowdinApiClient/Api/TranslationMemoryApiTest.php b/tests/CrowdinApiClient/Api/TranslationMemoryApiTest.php index 80fddb0d..673353c3 100644 --- a/tests/CrowdinApiClient/Api/TranslationMemoryApiTest.php +++ b/tests/CrowdinApiClient/Api/TranslationMemoryApiTest.php @@ -456,4 +456,10 @@ public function testCreateSegment() $this->assertInstanceOf(TranslationMemorySegment::class, $segment); $this->assertEquals(4, $segment->getId()); } + + public function testDeleteSegment() + { + $this->mockRequestDelete('/tms/4/segments/1'); + $this->crowdin->translationMemory->deleteSegment(4, 1); + } }