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

[FEATURE] Rework and centralize api client operation #189

Merged
merged 5 commits into from
May 5, 2023
Merged
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
159 changes: 159 additions & 0 deletions Classes/Client.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
<?php

declare(strict_types=1);

namespace WebVision\WvDeepltranslate;

use Psr\Http\Message\ResponseInterface;
use TYPO3\CMS\Core\Http\RequestFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use WebVision\WvDeepltranslate\Exception\ClientNotValidUrlException;

final class Client
{
private const API_VERSION = 'v2';

public const GLOSSARY_ENTRY_FORMAT = "%s\t%s\n";

/**
* @var Configuration
*/
private $configuration;

/**
* @var RequestFactory
*/
private $requestFactory;

public function __construct()
{
$this->configuration = GeneralUtility::makeInstance(Configuration::class);
$this->requestFactory = GeneralUtility::makeInstance(RequestFactory::class);
}

public function translate(string $content, string $sourceLang, string $targetLang, string $glossary = ''): ResponseInterface
{
$baseUrl = $this->buildBaseUrl('translate');

$postFields = [
'text' => $content,
'source_lang' => $sourceLang,
'target_lang' => $targetLang,
'tag_handling' => 'xml',
];

if (!empty($glossary)) {
$postFields['glossary_id'] = $glossary;
}

$postFields['formality'] = $this->configuration->getFormality();

return $this->requestFactory->request($baseUrl, 'POST', $this->mergeRequiredRequestOptions([
'form_params' => $postFields,
]));
}

public function getSupportedTargetLanguage(string $type = 'target'): ResponseInterface
{
$baseUrl = $this->buildBaseUrl('languages?type=' . $type);

return $this->requestFactory->request($baseUrl, 'GET', $this->mergeRequiredRequestOptions());
}

public function getGlossaryLanguagePairs(): ResponseInterface
{
$baseUrl = $this->buildBaseUrl('glossary-language-pairs');

return $this->requestFactory->request($baseUrl, 'GET', $this->mergeRequiredRequestOptions());
}

public function getAllGlossaries(): ResponseInterface
{
$baseUrl = $this->buildBaseUrl('glossaries');

return $this->requestFactory->request($baseUrl, 'GET', $this->mergeRequiredRequestOptions());
}

public function getGlossary(string $glossaryId): ResponseInterface
{
$baseUrl = $this->buildBaseUrl(sprintf('glossaries/%s', $glossaryId));

return $this->requestFactory->request($baseUrl, 'GET', $this->mergeRequiredRequestOptions());
}

public function createGlossary(
string $glossaryName,
string $sourceLang,
string $targetLang,
array $entries,
string $entriesFormat = 'tsv'
): ResponseInterface {
$baseUrl = $this->buildBaseUrl('glossaries');

$postFields = [
'name' => $glossaryName,
'source_lang' => $sourceLang,
'target_lang' => $targetLang,
'entries_format' => $entriesFormat,
];

$formatEntries = '';
foreach ($entries as $source => $target) {
$formatEntries .= sprintf(self::GLOSSARY_ENTRY_FORMAT, $source, $target);
}

$postFields['entries'] = $formatEntries;

return $this->requestFactory->request($baseUrl, 'POST', $this->mergeRequiredRequestOptions([
'form_params' => $postFields,
]));
}

public function deleteGlossary(string $glossaryId): ResponseInterface
{
$baseUrl = $this->buildBaseUrl(sprintf('glossaries/%s', $glossaryId));

return $this->requestFactory->request($baseUrl, 'DELETE', $this->mergeRequiredRequestOptions());
}

public function getGlossaryEntries(string $glossaryId): ResponseInterface
{
$baseUrl = $this->buildBaseUrl(sprintf('glossaries/%s/entries', $glossaryId));

return $this->requestFactory->request($baseUrl, 'GET', $this->mergeRequiredRequestOptions());
}

private function buildBaseUrl(string $path): string
{
$url = sprintf(
'%s://%s/%s/%s',
$this->configuration->getApiScheme(),
$this->configuration->getApiUrl(),
self::API_VERSION,
$path
);

if (!GeneralUtility::isValidUrl($url)) {
throw new ClientNotValidUrlException(sprintf('BaseURL "%s" is not valid', $url), 1676125513);
}

return $url;
}

/**
* @param array<string, mixed> $options
* @return array<string, mixed>
*/
private function mergeRequiredRequestOptions(array $options = []): array
{
return array_merge_recursive(
[
'headers' => [
'Authorization' => sprintf('DeepL-Auth-Key %s', $this->configuration->getApiKey()),
'User-Agent' => 'TYPO3.WvDeepltranslate/1.0',
],
],
$options
);
}
}
77 changes: 77 additions & 0 deletions Classes/Configuration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

declare(strict_types=1);

namespace WebVision\WvDeepltranslate;

use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
use TYPO3\CMS\Core\Utility\GeneralUtility;

class Configuration
{
/**
* @var string
*/
private $apiKey = '';

/**
* @var string
*/
private $apiUrl = '';

/**
* @var string
*/
private $formality = '';

public function __construct()
{
$extensionConfiguration = GeneralUtility::makeInstance(ExtensionConfiguration::class)->get('wv_deepltranslate');

if (isset($extensionConfiguration['apiKey'])) {
$this->apiKey = (string)$extensionConfiguration['apiKey'] ?? '';
}

if (isset($extensionConfiguration['apiUrl'])) {
// api url free is default
$this->apiUrl = (string)$extensionConfiguration['apiUrl'] ?? 'https://api-free.deepl.com/';
}

// In einer zukünftigen version sollte "Formality" in die SiteConfig verschoben werden
if (isset($extensionConfiguration['deeplFormality'])) {
$this->formality = (string)$extensionConfiguration['deeplFormality'] ?? 'default';
}
}

public function getApiKey(): string
{
return $this->apiKey;
}

public function getApiUrl(): string
{
return $this->getApiHost()
. ($this->getApiPort() ? ':' . $this->getApiPort() : '');
}

public function getApiScheme(): string
{
return parse_url($this->apiUrl)['scheme'] ?? 'https';
}

public function getApiHost(): string
{
return parse_url($this->apiUrl)['host'] ?? 'localhost';
}

public function getApiPort(): ?int
{
$port = parse_url($this->apiUrl)['port'] ?? null;
return $port ? (int)$port : null;
}

public function getFormality(): string
{
return $this->formality;
}
}
9 changes: 9 additions & 0 deletions Classes/Exception/ClientNotValidUrlException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace WebVision\WvDeepltranslate\Exception;

class ClientNotValidUrlException extends \Exception
{
}
Loading