simple_tmgmt-1.0.x-dev/modules/simple_tmgmt_deepl/src/Plugin/tmgmt/Translator/SimpleTmgmtDeeplTranslator.php
modules/simple_tmgmt_deepl/src/Plugin/tmgmt/Translator/SimpleTmgmtDeeplTranslator.php
<?php
namespace Drupal\simple_tmgmt_deepl\Plugin\tmgmt\Translator;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\tmgmt\Entity\Translator;
use Drupal\tmgmt\JobInterface;
use Drupal\tmgmt\TMGMTException;
use Drupal\tmgmt_deepl\Plugin\tmgmt\Translator\DeeplProTranslator;
use Drupal\simple_tmgmt\Plugin\tmgmt\Translator\MachineTranslatorInterface;
use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Psr7\Request;
/**
* Simple TMGMT DeepL Pro translator plugin.
*
* - Overrides the annotations.
* - Custom error handling on request.
* - Set checkout settings as always available.
*
* @TranslatorPlugin(
* id = "simple_tmgmt_deepl",
* label = @Translation("Simplified DeepL"),
* description = @Translation("Simplifies error messages and notifies on error by mail."),
* ui = "Drupal\simple_tmgmt_deepl\DeeplTranslatorUi",
* logo = "icons/deepl.svg",
* )
*/
class SimpleTmgmtDeeplTranslator extends DeeplProTranslator implements MachineTranslatorInterface, ContainerFactoryPluginInterface {
/**
* Local method to do request to DeepL Pro Translate service.
*
* @param \Drupal\tmgmt\Entity\Translator $translator
* The translator entity to get the settings from.
* @param array $query_params
* (Optional) Additional query params to be passed into the request.
* @param array $options
* (Optional) Additional options that will passed to drupal_http_request().
*
* @return array|object
* Unserialized JSON response from DeepL Pro.
*
* @throws TMGMTException
* - Unable to connect to the DeepL Pro Service
* - Error returned by the DeepL Pro Service.
*/
protected function doRequest(Translator $translator, array $query_params = [], array $options = []) {
$configFactory = \Drupal::configFactory();
/** @var \Drupal\simple_tmgmt\SimpleTmgmtInterface $simpleTmgmt */
$simpleTmgmt = \Drupal::service('simple_tmgmt');
$config = $configFactory->get('simple_tmgmt.settings');
// Get custom URL for testing purposes, if available.
$custom_url = $translator->getSetting('url');
$url = $custom_url ? $custom_url : $this->translatorUrl;
// Define headers.
$headers = [
'Content-Type' => 'application/x-www-form-urlencoded',
];
// Build the query.
$query_string = '';
$query_string .= '&auth_key=' . $translator->getSetting('auth_key');
// Add text to be translated.
if (isset($query_params[$this->qParamName])) {
foreach ($query_params[$this->qParamName] as $source_text) {
$query_string .= '&text=' . urlencode($source_text);
}
}
// Add source language.
if (isset($query_params['source_lang'])) {
$query_string .= '&source_lang=' . $query_params['source_lang'];
}
// Add target language.
if (isset($query_params['target_lang'])) {
$query_string .= '&target_lang=' . $query_params['target_lang'];
}
// Add additional settings.
if (!empty($translator->getSetting('tag_handling'))) {
$query_string .= '&tag_handling=' . urlencode($translator->getSetting('tag_handling'));
}
if (!empty($translator->getSetting('non_splitting_tags'))) {
$query_string .= '&non_splitting_tags=' . urlencode($translator->getSetting('non_splitting_tags'));
}
if (!empty($translator->getSetting('ignore_tags'))) {
$query_string .= '&ignore_tags=' . urlencode($translator->getSetting('ignore_tags'));
}
// Split sentences/ preserve formatting are set as required options.
$query_string .= '&split_sentences=' . $translator->getSetting('split_sentences');
$query_string .= '&preserve_formatting=' . $translator->getSetting('preserve_formatting');
// Build request object.
$request = new Request('POST', $url, $headers, $query_string);
// Send the request with the query.
$errorCode = NULL;
$errorMessage = '';
try {
$response = $this->client->send($request);
}
// Bad response.
catch (BadResponseException $exception) {
$errorCode = $exception->getCode();
$errorMessage = 'DeepL Pro service returned the following error - ' . $exception->getMessage();;
}
// No connectivity.
catch (GuzzleException $exception) {
$errorCode = $exception->getCode();
$errorMessage = 'Guzzle exception - ' . $exception->getMessage();
}
// Other exception.
catch (\Exception $exception) {
$errorCode = $exception->getCode();
$errorMessage = $exception->getMessage();
} finally {
// Catch all to send a mail and dispatch a TMGMT exception.
if ($errorCode !== NULL) {
$mailAddress = $config->get('error_notification_email');
// Default frontend message, that can be overridden.
$frontendMessage = $this->t('@error_code. A mail has been sent to @mail.', [
'@error_code' => $errorCode,
'@mail' => $mailAddress,
]);
$mailMessage = '';
switch ($errorCode) {
case 400:
$mailMessage = $this->t('Bad request. Please check error message and your parameters.');
break;
case 403:
$mailMessage = $this->t('Authorization failed. Please supply a valid auth_key parameter.');
break;
case 404:
$mailMessage = $this->t('The requested resource could not be found.');
break;
case 413:
$mailMessage = $this->t('The request size exceeds the limit.');
break;
case 429:
$mailMessage = $this->t('Too many requests. Please wait and resend your request.');
break;
case 456:
$mailMessage = $this->t('Quota exceeded. The character limit has been reached.');
break;
case 503:
$mailMessage = $this->t('Resource currently unavailable. Try again later.');
break;
default:
break;
}
// Original error.
$originalError = $this->t('<pre>[Error @error_code] @error_message</pre>', [
'@error_code' => $errorCode,
'@error_message' => $errorMessage,
]);
// Prepares the message content.
$mailContent = [
'message' => $mailMessage,
'text' => $source_text,
'error_code' => $errorCode,
'original_error' => $originalError,
'translator' => $translator->id(),
'source_language' => $query_params['source_lang'],
'target_language' => $query_params['target_lang'],
];
$simpleTmgmt->sendJobErrorMail($mailContent, $mailAddress);
throw new TMGMTException($frontendMessage);
}
}
// Process the JSON result into array.
return json_decode($response->getBody(), TRUE);
}
/**
* {@inheritdoc}
*/
public function hasCheckoutSettings(JobInterface $job) {
// Always true as the privacy checkbox is required.
return TRUE;
}
}
