Server : LiteSpeed System : Linux server321.web-hosting.com 4.18.0-513.18.1.lve.el8.x86_64 #1 SMP Thu Feb 22 12:55:50 UTC 2024 x86_64 User : apotdzgr ( 7060) PHP Version : 8.0.30 Disable Function : NONE Directory : /home/apotdzgr/snelapotheeks.com/wp-content/plugins/loco-translate/src/api/ |
Upload File : |
<?php /** * DeepL back end client, because CORS */ abstract class Loco_api_DeepL extends Loco_api_Client { /** * @param string[][] $items input messages with keys, "source", "context" and "notes" * * @return string[] Translated strings * @throws Loco_error_Exception */ public static function process( array $items, Loco_Locale $locale, array $config ): array { $api_key = $config['key']; if( ! is_string($api_key) || '' === $api_key ){ throw new Loco_error_Exception('API key required'); } // target language requires mapping to DeepL supported value // https://developers.deepl.com/docs/getting-started/supported-languages#target-languages $targetLang = strtoupper($locale->lang); if( $locale->region ){ $variants = [ 'EN-GB' => 'EN-GB', 'EN-US' => 'EN-US', 'PT-PT' => 'PT-PT', 'PT-BR' => 'PT-BR', 'ZH-CN' => 'ZH-HANS', 'ZH-SG' => 'ZH-HANS', 'ZH-TW' => 'ZH-HANT', 'ZH-HK' => 'ZH-HANT', ]; $tag = $targetLang.'-'.strtoupper($locale->region); if( array_key_exists($tag,$variants) ){ $targetLang = $variants[$tag]; } } // DeepL supported formality $tones = [ 'formal' => 'prefer_more', 'informal' => 'prefer_less', '' => 'default', ]; $formality = $tones[ $locale->getFormality() ] ?? $tones['']; // source language may be overridden by `loco_api_provider_source` hook $sourceLang = 'EN'; $tag = Loco_mvc_PostParams::get()['source']; if( is_string($tag) && '' !== $tag ){ $source = Loco_Locale::parse($tag); if( $source->isValid() ){ $sourceLang = strtoupper($source->lang); } } // Unwind all posted sources // TODO perform placeholder protection here, as per Loco platform. $sources = []; foreach( $items as $item ){ $sources[] = $item['source']; } // context can only be set per request, for all text values posted, if( 1 === count($items) ){ $context = trim( implode(' ', [ $items[0]['context']??'', $items[0]['notes']??'' ] ) ); // Detect key verification call here and perform a zero cost /v2/usage request if( '' === $context && 'OK' === $sources[0] && 'FR' === $targetLang ){ return self::fetch_usage($api_key) ? ['OK'] : []; } } else { $context = ''; } // make request and parse JSON result $result = wp_remote_request( self::baseUrl($api_key).'/v2/translate', self::init_request_arguments( $config, [ 'source_lang' => apply_filters('loco_deepl_source_lang',$sourceLang), 'target_lang' => apply_filters('loco_deepl_target_lang',$targetLang, $locale), 'formality' => apply_filters('loco_deepl_formality',$formality, $locale), 'preserve_formatting' => '1', 'context' => $context, 'text' => $sources, ] ) ); $data = parent::decodeResponse($result); $status = $result['response']['code']; if( 200 !== $status ){ $message = $data['message'] ?? 'Unknown error'; throw new Loco_error_Exception( sprintf('DeepL returned status %u: %s',$status,$message) ); } // 200 OK: $targets = []; $translations = $data['translations']??[]; foreach( $translations as $translation ){ $targets[] = $translation['text']; } return $targets; } private static function init_request_arguments( array $config, array $data ):array { return [ 'method' => 'POST', 'redirection' => 0, 'user-agent' => parent::getUserAgent(), 'reject_unsafe_urls' => false, 'headers' => [ 'Content-Type' => 'application/x-www-form-urlencoded', 'Authorization' => 'DeepL-Auth-Key '.$config['key'], ], 'body' => self::encode_request_body($data), ]; } /** * DeepL requires arrays to be specified as repeated arguments * e.g. text=foo&text=bar&text=baz */ private static function encode_request_body( array $data ): string { $pairs = []; foreach( $data as $key => $mixed ){ if( is_array($mixed) ){ foreach( $mixed as $scalar ){ $pairs[] = $key.'='.urlencode($scalar); } } else { $pairs[] = $key.'='.urlencode($mixed); } } return implode('&',$pairs); } private static function fetch_usage( string $key ):array { $data = parent::decodeResponse( wp_remote_request( self::baseUrl($key).'/v2/usage', [ 'redirection' => 0, 'user-agent' => parent::getUserAgent(), 'reject_unsafe_urls' => false, 'headers' => [ 'Authorization' => 'DeepL-Auth-Key '.$key, ], ] ) ); if( array_key_exists('character_limit',$data) ){ return $data; } $message = $data['message'] ?? 'Failed to get usage'; throw new Loco_error_Exception( 'DeepL: '.$message); } private static function baseUrl( string $key ):string { $url = 'https://api'; if( str_ends_with($key,':fx') ){ $url .= '-free'; } return $url . '.deepl.com'; } }