在 PHP 中通过 CustomTranslator API 导入文档
Import Document via CustomTranslator API in PHP
我正在尝试通过 PHP 中的 Microsoft 自定义翻译器 API 导入 TMX 文件。不幸的是,我一直 运行 进入以下错误:
"DocumentDetails must follow type IEnumerable[ImportDocumentRequestDetails]."
我已经成功地向 API 发出了其他请求(虽然只有 GET
),所以我很难弄清楚这个请求。
到目前为止,我已经尝试了请求的各种排列组合,主要是通过反复试验。我已经尝试通过在门户中上传相同的文件来复制请求,这没有问题地成功了,但我无法在 PHP (7.3) 中复制它。
我还尝试对 GitHub 上的 C# API 示例进行逆向工程。不幸的是,我的 C# 知识并不那么敏锐,而且我确信我遗漏了一些细微差别。我注意到示例使用了 'Language' 字符串,而门户网站似乎使用了 'LanguageCode',以及其他不一致的地方,这并没有使解决这个问题变得容易得多。
我的代码的精简版本,只有相关部分(可以假定有效的访问令牌和本地文件路径到有效的 .tmx
)如下:
Class CustomTranslator {
private $curl;
private $aAccessToken; // valid, working token
// Set up connection and login with initial user
public function __construct() {
$this->curl = curl_init();
$aOptions = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_TIMEOUT => 60
);
curl_setopt_array($this->curl, $aOptions);
}
function ImportParallelDocument($strFilePath) {
$aRequestContent = [
'Files' => new CURLFile($strFilePath, mime_content_type($strFilePath), basename($strFilePath)),
'DocumentDetails' => [
'DocumentName' => basename($strFilePath),
'DocumentType' => 'training',
'IsParallel' => true,
'FileDetails' => [
'Name' => $strFilePath,
'Language' => 'Dutch',
'Type' => pathinfo($strFilePath, PATHINFO_EXTENSION),
'OverwriteIfExists' => true
]
]
];
return $this->Request("v1.0/documents/import?workspaceId=".CUSTOMTRANSLATOR_WORKSPACEID, $aRequestContent, 'POST');
}
// Prototype request function
private function Request($strRequest, $aData = array(), $strMethod = 'GET') {
$strRequest = CUSTOMTRANSLATOR_API_URL.$strRequest;
// Reset between requests
curl_setopt($this->curl, CURLOPT_POST, false);
curl_setopt($this->curl, CURLOPT_HTTPHEADER, ['Authorization: Bearer '.$this->aAccessToken['access_token']]);
if(isset($aData['authorization'])) $aData['authorization'] = $this->aAccessToken['access_token'];
if ($strMethod == 'GET') {
$strRequest .= "?".http_build_query($aData);
}
else {
curl_setopt($this->curl, CURLOPT_POST, true);
curl_setopt($this->curl, CURLOPT_HTTPHEADER, ['Authorization: Bearer '.$this->aAccessToken['access_token'],
'X-HTTP-Method-Override: '.$strMethod]);
curl_setopt($this->curl, CURLOPT_POSTFIELDS, $aData);
}
curl_setopt($this->curl, CURLOPT_URL, $strRequest);
$strResponse = curl_exec($this->curl);
// Return the JSON array if it can be decoded, otherwise the actual curl response
return json_decode($strResponse, true)?:$strResponse;
}
}
如前所述,当我尝试使用上述代码上传文件时,我收到的确切错误是 {"message":"DocumentDetails must follow type IEnumerable[ImportDocumentRequestDetails].","display":false}
,遗憾的是没有进一步说明丢失或不正确的内容。我希望成功导入通过门户本身成功导入的 TMX 文件,据我所知实现了相同的 API.
我想我只是遗漏了一些东西,或者做的事情不太正确,所以我们将不胜感激!
在同事的帮助下,想出了一个暂时解决的方法,只需提供与门户中使用的调用等效的 JSON:
$aRequestContent = [
'Files' => new CURLFile($strFilePath, mime_content_type($strFilePath), basename($strFilePath)),
'DocumentDetails' =>
'[{ "DocumentName": "",
"DocumentType": "training",
"FileDetails": [{
"Name": "'.basename($strFilePath).'",
"LanguageCode": "en",
"OverwriteIfExists": true }]
}]'
];
这不是最好的解决方案,但出于预览的目的 API,它现在可以使用(直到它最终不可避免地投入生产,唉)。
仔细检查 JSON 让我发现了嵌套数组结构(可能用于多文件上传),起初我并不明显。但是,以下数组结构足以处理请求:
$aDocumentDetails = [[ // Note the nested array here, for index numbering
'DocumentName' => '',
'DocumentType' => ucfirst($strType),
'FileDetails' => [[ // As well as here
'Name' => basename($strFilePath),
'LanguageCode' => $strLanguageCode,
'OverwriteIfExists' => $bOverwrite
]]
]];
$aRequestContent = [
'Files' => new CURLFile($strFilePath, mime_content_type($strFilePath), basename($strFilePath)),
'DocumentDetails' => json_encode($aDocumentDetails)
];
简而言之,API 需要索引子数组中的 DocumentDetails(和 FileDetails):
[0 => [ 'DocumentName' => ...,
'FileDetails' => [0 => ['Name' => ...]
];
理解这个花絮对我帮助很大。
我正在尝试通过 PHP 中的 Microsoft 自定义翻译器 API 导入 TMX 文件。不幸的是,我一直 运行 进入以下错误:
"DocumentDetails must follow type IEnumerable[ImportDocumentRequestDetails]."
我已经成功地向 API 发出了其他请求(虽然只有 GET
),所以我很难弄清楚这个请求。
到目前为止,我已经尝试了请求的各种排列组合,主要是通过反复试验。我已经尝试通过在门户中上传相同的文件来复制请求,这没有问题地成功了,但我无法在 PHP (7.3) 中复制它。
我还尝试对 GitHub 上的 C# API 示例进行逆向工程。不幸的是,我的 C# 知识并不那么敏锐,而且我确信我遗漏了一些细微差别。我注意到示例使用了 'Language' 字符串,而门户网站似乎使用了 'LanguageCode',以及其他不一致的地方,这并没有使解决这个问题变得容易得多。
我的代码的精简版本,只有相关部分(可以假定有效的访问令牌和本地文件路径到有效的 .tmx
)如下:
Class CustomTranslator {
private $curl;
private $aAccessToken; // valid, working token
// Set up connection and login with initial user
public function __construct() {
$this->curl = curl_init();
$aOptions = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_TIMEOUT => 60
);
curl_setopt_array($this->curl, $aOptions);
}
function ImportParallelDocument($strFilePath) {
$aRequestContent = [
'Files' => new CURLFile($strFilePath, mime_content_type($strFilePath), basename($strFilePath)),
'DocumentDetails' => [
'DocumentName' => basename($strFilePath),
'DocumentType' => 'training',
'IsParallel' => true,
'FileDetails' => [
'Name' => $strFilePath,
'Language' => 'Dutch',
'Type' => pathinfo($strFilePath, PATHINFO_EXTENSION),
'OverwriteIfExists' => true
]
]
];
return $this->Request("v1.0/documents/import?workspaceId=".CUSTOMTRANSLATOR_WORKSPACEID, $aRequestContent, 'POST');
}
// Prototype request function
private function Request($strRequest, $aData = array(), $strMethod = 'GET') {
$strRequest = CUSTOMTRANSLATOR_API_URL.$strRequest;
// Reset between requests
curl_setopt($this->curl, CURLOPT_POST, false);
curl_setopt($this->curl, CURLOPT_HTTPHEADER, ['Authorization: Bearer '.$this->aAccessToken['access_token']]);
if(isset($aData['authorization'])) $aData['authorization'] = $this->aAccessToken['access_token'];
if ($strMethod == 'GET') {
$strRequest .= "?".http_build_query($aData);
}
else {
curl_setopt($this->curl, CURLOPT_POST, true);
curl_setopt($this->curl, CURLOPT_HTTPHEADER, ['Authorization: Bearer '.$this->aAccessToken['access_token'],
'X-HTTP-Method-Override: '.$strMethod]);
curl_setopt($this->curl, CURLOPT_POSTFIELDS, $aData);
}
curl_setopt($this->curl, CURLOPT_URL, $strRequest);
$strResponse = curl_exec($this->curl);
// Return the JSON array if it can be decoded, otherwise the actual curl response
return json_decode($strResponse, true)?:$strResponse;
}
}
如前所述,当我尝试使用上述代码上传文件时,我收到的确切错误是 {"message":"DocumentDetails must follow type IEnumerable[ImportDocumentRequestDetails].","display":false}
,遗憾的是没有进一步说明丢失或不正确的内容。我希望成功导入通过门户本身成功导入的 TMX 文件,据我所知实现了相同的 API.
我想我只是遗漏了一些东西,或者做的事情不太正确,所以我们将不胜感激!
在同事的帮助下,想出了一个暂时解决的方法,只需提供与门户中使用的调用等效的 JSON:
$aRequestContent = [
'Files' => new CURLFile($strFilePath, mime_content_type($strFilePath), basename($strFilePath)),
'DocumentDetails' =>
'[{ "DocumentName": "",
"DocumentType": "training",
"FileDetails": [{
"Name": "'.basename($strFilePath).'",
"LanguageCode": "en",
"OverwriteIfExists": true }]
}]'
];
这不是最好的解决方案,但出于预览的目的 API,它现在可以使用(直到它最终不可避免地投入生产,唉)。
仔细检查 JSON 让我发现了嵌套数组结构(可能用于多文件上传),起初我并不明显。但是,以下数组结构足以处理请求:
$aDocumentDetails = [[ // Note the nested array here, for index numbering
'DocumentName' => '',
'DocumentType' => ucfirst($strType),
'FileDetails' => [[ // As well as here
'Name' => basename($strFilePath),
'LanguageCode' => $strLanguageCode,
'OverwriteIfExists' => $bOverwrite
]]
]];
$aRequestContent = [
'Files' => new CURLFile($strFilePath, mime_content_type($strFilePath), basename($strFilePath)),
'DocumentDetails' => json_encode($aDocumentDetails)
];
简而言之,API 需要索引子数组中的 DocumentDetails(和 FileDetails):
[0 => [ 'DocumentName' => ...,
'FileDetails' => [0 => ['Name' => ...]
];
理解这个花絮对我帮助很大。