Code development platform for open source projects from the European Union institutions :large_blue_circle: EU Login authentication by SMS has been phased out. To see alternatives please check here

Skip to content
Snippets Groups Projects
Commit 3950e752 authored by Davis Ragels's avatar Davis Ragels
Browse files

Compatibility improvements & MT provider setup help text updates

parent 7621ec88
Branches
Tags
No related merge requests found
......@@ -2,46 +2,32 @@
namespace Drupal\webt;
use Drupal\Core\File\FileUrlGeneratorInterface;
use Drupal\Core\Extension\ExtensionPathResolver;
use Drupal\Core\Url;
/**
* Service that generates public URL for assets (e.g. images).
*/
class AssetManager {
/**
* The file URL generator service.
*
* @var \Drupal\Core\File\FileUrlGeneratorInterface
*/
protected $fileUrlGenerator;
/**
* Extension path resolver
*
* @var \Drupal\Core\Extension\ExtensionPathResolver
*/
protected $extensionPathResolver;
/**
* Constructs a new instance of the class.
*
* @param \Drupal\Core\File\FileUrlGeneratorInterface $fileUrlGenerator The file URL generator service.
* @param \Drupal\Core\Extension\ExtensionPathResolver $extensionPathResolver Extension path resolver.
*/
public function __construct( FileUrlGeneratorInterface $fileUrlGenerator, ExtensionPathResolver $extensionPathResolver ) {
$this->fileUrlGenerator = $fileUrlGenerator;
$this->extensionPathResolver = $extensionPathResolver;
}
/**
* Retrieves full asset URL from relative path
*
* @param string $relative_path Path to asset.
* @return Drupal\Core\Url
* @return string
*/
public function getAssetUrl( $relative_path ) {
$relative_path = $this->extensionPathResolver->getPath( 'module', 'webt' ) . "/$relative_path";
return $this->fileUrlGenerator->generate( "$relative_path" );
$module_path = \Drupal::service( 'module_handler' )
->getModule( 'webt' )
->getPath();
$language_manager = \Drupal::languageManager();
$current_language = $language_manager->getCurrentLanguage()->getId();
$home_url = Url::fromRoute( '<front>', array(), array( 'absolute' => true ) )->toString();
// Remove language code from URL if present.
if ( str_ends_with( $home_url, '/' . $current_language ) ) {
$home_url = substr( $home_url, 0, strlen( $home_url ) - strlen( $current_language ) );
}
return "$home_url/$module_path/$relative_path";
}
}
......@@ -32,8 +32,8 @@ class AboutTabController extends ControllerBase {
$learn_more_link = 'https://website-translation.language-tools.ec.europa.eu/web-t-connecting-languages-0_en';
$asset_manager = \Drupal::service( 'webt.asset_manager' );
$ec_logotype_url = $asset_manager->getAssetUrl( 'images/ec_logotype.svg' )->toString();
$webt_logotype_url = $asset_manager->getAssetUrl( 'images/webt_logotype.svg' )->toString();
$ec_logotype_url = $asset_manager->getAssetUrl( 'images/ec_logotype.svg' );
$webt_logotype_url = $asset_manager->getAssetUrl( 'images/webt_logotype.svg' );
$text = "
<h5>$about_heading</h5>
......
......@@ -4,6 +4,7 @@ namespace Drupal\webt\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\webt\translation_engines\etranslation\EtranslationService;
use Drupal\webt\translation_engines\etranslation\EtranslationUtils;
use Drupal\webt\translation_engines\generic\GenericMTService;
......@@ -99,6 +100,22 @@ class TranslationProviderForm extends FormBase {
'disabled' => $condition_generic_mt,
),
),
'etranslation_help' => array(
'#type' => 'container',
'#attributes' => array( 'class' => array( 'form-item__description' ) ),
'#states' => array(
'visible' => $condition_etranslation,
),
'help_text' => array(
'#type' => 'markup',
'#markup' => new FormattableMarkup(
t( "Set up an account for <a target='_blank' href='@link'>eTranslation</a>" ),
array(
'@link' => 'https://website-translation.language-tools.ec.europe.eu/automated-translation_en',
)
),
),
),
'mt_api_url' => array(
'#type' => 'textfield',
'#title' => $this->t( 'Base URL' ),
......@@ -120,6 +137,22 @@ class TranslationProviderForm extends FormBase {
'disabled' => $condition_etranslation,
),
),
'mt_api_help' => array(
'#type' => 'container',
'#attributes' => array( 'class' => array( 'form-item__description' ) ),
'#states' => array(
'visible' => $condition_generic_mt,
),
'help_text' => array(
'#type' => 'markup',
'#markup' => new FormattableMarkup(
t( "Get <a target='_blank' href='@link'>MT provider access</a>" ),
array(
'@link' => 'https://website-translation.language-tools.ec.europe.eu/automated-translation_en',
)
),
),
),
'button_wrapper' => array(
'#type' => 'container',
'#attributes' => array( 'class' => array( 'text-align-right' ) ),
......
......@@ -9,7 +9,7 @@ class TranslationResponse {
/**
* Translation status.
*
* @var TranslationStatus
* @var int
*/
public $status;
/**
......@@ -23,9 +23,9 @@ class TranslationResponse {
* Sets response translations and status
*
* @param string[] $translations Translations.
* @param TranslationStatus $status Status.
* @param int $status Status.
*/
public function __construct( $translations, $status = TranslationStatus::FullResult ) {
public function __construct( $translations, $status = TranslationStatus::FULL_RESULT ) {
$this->translations = $translations;
$this->status = $status;
}
......
......@@ -5,11 +5,11 @@ namespace Drupal\webt\Model;
/**
* Multi-request translation status.
*/
enum TranslationStatus {
class TranslationStatus {
// Translation failed.
case NoResult;
const NO_RESULT = -1;
// Some translation requests were successful, but translation could not be finished.
case PartialResult;
const PARTIAL_RESULT = 0;
// All translation requests were succcessful.
case FullResult;
const FULL_RESULT = 1;
}
......@@ -90,7 +90,7 @@ class TranslationManager {
$trg_lang = $key_parts[1];
$translation_response = $this->translation_service->translate( $src_lang, $trg_lang, $strings_to_translate, $type );
if ( empty( $translation_response->translations ) || TranslationStatus::FullResult !== $translation_response->status ) {
if ( empty( $translation_response->translations ) || TranslationStatus::FULL_RESULT !== $translation_response->status ) {
continue;
}
......@@ -151,7 +151,7 @@ class TranslationManager {
if ( ! $translations ) {
$translation_response = $this->translation_service->translate( $src_lang, $trg_lang, $strings_to_translate, 'entity', false, $entity->id() );
$translations = $translation_response->translations;
if ( TranslationStatus::FullResult !== $translation_response->status ) {
if ( TranslationStatus::FULL_RESULT !== $translation_response->status ) {
return;
}
}
......@@ -285,7 +285,7 @@ class TranslationManager {
$translations = $translation_response->translations;
// replace source values with translations & save.
if ( ! empty( $translations ) && TranslationStatus::FullResult === $translation_response->status ) {
if ( ! empty( $translations ) && TranslationStatus::FULL_RESULT === $translation_response->status ) {
$collection = \Drupal::service( 'config.storage' )->createCollection( "language.$langcode" );
foreach ( $config_strings as $key => $value ) {
$translated_data = $value;
......
......@@ -127,7 +127,7 @@ abstract class AbstractTranslationService {
$json_string = $config->get( $key );
if ( ! $json_string ) {
$response = $this->send_language_direction_request();
if ( 200 === $response->getStatusCode() ) {
if ( $response && 200 === $response->getStatusCode() ) {
$json_string = $this->map_language_direction_response_body( $response->getBody() );
$config->set( $key, $json_string );
$config->save();
......@@ -229,7 +229,7 @@ abstract class AbstractTranslationService {
}
// translate XML[].
\Drupal::logger( WEBT_LOGGER )->debug( "Sending $lang_from-$lang_to translation request " . $i + 1 . '/' . $request_count . ' (' . count( $translatable_values ) . ' strings)' );
\Drupal::logger( WEBT_LOGGER )->debug( "Sending $lang_from-$lang_to translation request " . ((string) ($i + 1)) . '/' . (string) $request_count . ' (' . ((string) count( $translatable_values )) . ' strings)' );
$xml_translations = $this->send_translation_request( $lang_from, $lang_to, $translatable_values, $entity_id );
if ( ! $xml_translations || empty( $xml_translations ) ) {
......@@ -246,7 +246,7 @@ abstract class AbstractTranslationService {
if ( $request_count > 1 ) {
\Drupal::logger( WEBT_LOGGER )->error( 'One of translation requests failed. Please check if machine translation provider API is working or reduce the "Max characters per single request" value (in Translation provider configuration) and try again!' );
}
return new TranslationResponse( $full_result, empty( $full_result ) ? TranslationStatus::NoResult : TranslationStatus::PartialResult );
return new TranslationResponse( $full_result, empty( $full_result ) ? TranslationStatus::NO_RESULT : TranslationStatus::PARTIAL_RESULT );
}
}
......@@ -266,7 +266,7 @@ abstract class AbstractTranslationService {
$percentage_completed += 100 / $request_count;
$this->update_progress_info( $percentage_completed, $object_type, $lang_from, $lang_to, $entity_id );
}
return new TranslationResponse( $full_result, TranslationStatus::FullResult );
return new TranslationResponse( $full_result, TranslationStatus::FULL_RESULT );
}
/**
......@@ -276,6 +276,10 @@ abstract class AbstractTranslationService {
*/
public function test_connection() {
$response = $this->send_language_direction_request();
if ( ! $response ) {
\Drupal::logger( WEBT_LOGGER )->error( 'Response object is null. Please check if MT service can be reached.' );
return false;
}
$content_type = isset( $response->getHeaders()['Content-Type'] ) ? $response->getHeaders()['Content-Type'][0] : null;
if ( $content_type && ! str_contains( $content_type, 'application/json' ) ) {
\Drupal::logger( WEBT_LOGGER )->error( "Invalid content type '$content_type' in language direction response!" );
......@@ -416,6 +420,11 @@ abstract class AbstractTranslationService {
$original_child_node = $original_node->lastChild;
$encoded_child_node = $encoded_node->lastChild;
while ( $original_child_node && $encoded_child_node ) {
// Skip any extra text nodes in original HTML (fix for Drupal 8 which inserts newlines between paragraph nodes).
while ( $original_child_node && $encoded_child_node && XML_TEXT_NODE === $original_child_node->nodeType && XML_TEXT_NODE !== $encoded_child_node->nodeType ) {
$original_child_node = $original_child_node->previousSibling;
}
$this->replace_text_nodes_bottom_up( $original_child_node, $encoded_child_node );
$original_child_node = $original_child_node->previousSibling;
$encoded_child_node = $encoded_child_node->previousSibling;
......
......@@ -205,9 +205,10 @@ class EtranslationService extends AbstractTranslationService {
return array();
}
} catch ( \GuzzleHttp\Exception\RequestException $e ) {
$message = (string) $e->getResponse()->getBody();
if ( strlen( $message ) == 0 ) {
$message = Psr7\Message::toString( $e->getResponse() );
$response = $e->getResponse();
$message = $response ? (string) $response->getBody() : '';
if ( $response && strlen( $message ) == 0 ) {
$message = \GuzzleHttp\Psr7\Message::toString( $response );
}
\Drupal::logger( WEBT_LOGGER )->error( 'Error translating strings: ' . $message );
return array();
......@@ -323,12 +324,13 @@ class EtranslationService extends AbstractTranslationService {
try {
return $this->http_client->get( self::$api_url . '/get-domains', $options );
} catch ( \GuzzleHttp\Exception\RequestException $e ) {
$message = (string) $e->getResponse()->getBody();
if ( strlen( $message ) == 0 ) {
$message = \GuzzleHttp\Psr7\Message::toString( $e->getResponse() );
$response = $e->getResponse();
$message = $response ? (string) $response->getBody() : '';
if ( $response && strlen( $message ) == 0 ) {
$message = \GuzzleHttp\Psr7\Message::toString( $response );
}
\Drupal::logger( WEBT_LOGGER )->error( 'Error on language direction request: ' . $message );
return $e->getResponse();
return $response;
} catch ( \GuzzleHttp\Exception\ConnectException $e ) {
\Drupal::logger( WEBT_LOGGER )->error( 'Could not establish connection with eTranslation. Error: ' . $e->getMessage() );
return new \GuzzleHttp\Psr7\Response( 408 );
......
......@@ -73,9 +73,10 @@ class GenericMTService extends AbstractTranslationService {
);
return $translations;
} catch ( \GuzzleHttp\Exception\RequestException $e ) {
$message = (string) $e->getResponse()->getBody();
if ( strlen( $message ) == 0 ) {
$message = Psr7\Message::toString( $e->getResponse() );
$response = $e->getResponse();
$message = $response ? (string) $response->getBody() : '';
if ( $response && strlen( $message ) == 0 ) {
$message = \GuzzleHttp\Psr7\Message::toString( $response );
}
\Drupal::logger( WEBT_LOGGER )->error( 'Error translating strings: ' . $message );
return array();
......@@ -104,12 +105,13 @@ class GenericMTService extends AbstractTranslationService {
try {
return $this->http_client->get( $api_url . '/translate/language-directions', $options );
} catch ( \GuzzleHttp\Exception\RequestException $e ) {
$message = (string) $e->getResponse()->getBody();
if ( strlen( $message ) == 0 ) {
$message = \GuzzleHttp\Psr7\Message::toString( $e->getResponse() );
$response = $e->getResponse();
$message = $response ? (string) $response->getBody() : '';
if ( $response && strlen( $message ) == 0 ) {
$message = \GuzzleHttp\Psr7\Message::toString( $response );
}
\Drupal::logger( WEBT_LOGGER )->error( 'Error on language direction request: ' . $message );
return $e->getResponse();
return $response;
} catch ( \GuzzleHttp\Exception\ConnectException $e ) {
\Drupal::logger( WEBT_LOGGER )->error( 'Could not establish connection with the MT provider. Check your API URL or try again later! Error: ' . $e->getMessage() );
return new \GuzzleHttp\Psr7\Response( 408 );
......
......@@ -3,7 +3,7 @@ description: Automated website content translation with WEB-T module
package: Multilingual
type: module
version: 1.0
core_version_requirement: ^9 || ^10
core_version_requirement: ^8 || ^9 || ^10
configure: webt.settings
dependencies:
......
......@@ -10,4 +10,4 @@ services:
arguments: ['@config.factory']
webt.asset_manager:
class: Drupal\webt\AssetManager
arguments: ['@file_url_generator', '@extension.path.resolver']
\ No newline at end of file
arguments: []
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment