nshelper

Translation Class

Sep 19th, 2026 (edited)
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 9.33 KB | None | 0 0
  1. <?php
  2.  
  3. declare(strict_types=1);
  4.  
  5. interface TranslationProviderInterface
  6. {
  7.     /**
  8.      * @param string      $text       Text to translate
  9.      * @param string      $targetLang Target language code (format depends on provider)
  10.      * @param string|null $sourceLang Source language code, or null for auto-detect
  11.      * @return string Translated text
  12.      * @throws RuntimeException on request failure
  13.      */
  14.     public function translate(string $text, string $targetLang, ?string $sourceLang = null): string;
  15. }
  16.  
  17. // ---------------------------------------------------------------------
  18. // Small shared HTTP helper (cURL) so providers don't duplicate this
  19. // ---------------------------------------------------------------------
  20. final class HttpClient
  21. {
  22.     /**
  23.      * @param array<string> $headers
  24.      * @param string|array  $body    Raw string (JSON/form-encoded) or array for multipart
  25.      */
  26.     public static function post(string $url, array $headers, $body): array
  27.     {
  28.         $ch = curl_init($url);
  29.         curl_setopt_array($ch, [
  30.             CURLOPT_RETURNTRANSFER => true,
  31.             CURLOPT_POST => true,
  32.             CURLOPT_HTTPHEADER => $headers,
  33.             CURLOPT_POSTFIELDS => $body,
  34.             CURLOPT_TIMEOUT => 15,
  35.             CURLOPT_CONNECTTIMEOUT => 10,
  36.         ]);
  37.  
  38.         $response = curl_exec($ch);
  39.  
  40.         if ($response === false) {
  41.             $error = curl_error($ch);
  42.             curl_close($ch);
  43.             throw new RuntimeException("cURL error: {$error}");
  44.         }
  45.  
  46.         $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  47.         curl_close($ch);
  48.  
  49.         if ($statusCode < 200 || $statusCode >= 300) {
  50.             throw new RuntimeException("HTTP error {$statusCode}: {$response}");
  51.         }
  52.  
  53.         $decoded = json_decode($response, true);
  54.         if (json_last_error() !== JSON_ERROR_NONE) {
  55.             throw new RuntimeException('Failed to decode JSON response: ' . json_last_error_msg());
  56.         }
  57.  
  58.         return $decoded ?? [];
  59.     }
  60. }
  61.  
  62. // ---------------------------------------------------------------------
  63. // Provider: DeepL (https://www.deepl.com/docs-api)
  64. // Target lang example: 'DE', 'ES', 'FR' (uppercase)
  65. // ---------------------------------------------------------------------
  66. final class DeepLProvider implements TranslationProviderInterface
  67. {
  68.     private string $apiKey;
  69.     private string $endpoint;
  70.  
  71.     public function __construct(string $apiKey, bool $useFreeTier = false)
  72.     {
  73.         $this->apiKey = $apiKey;
  74.         $this->endpoint = $useFreeTier
  75.             ? 'https://api-free.deepl.com/v2/translate'
  76.             : 'https://api.deepl.com/v2/translate';
  77.     }
  78.  
  79.     public function translate(string $text, string $targetLang, ?string $sourceLang = null): string
  80.         {
  81.             $params = [
  82.                 'text'        => $text,
  83.                 'target_lang' => strtoupper($targetLang),
  84.             ];
  85.  
  86.             if ($sourceLang !== null) {
  87.                 $params['source_lang'] = strtoupper($sourceLang);
  88.             }
  89.  
  90.             $result = HttpClient::post(
  91.                 $this->endpoint,
  92.                 [
  93.                     'Authorization: DeepL-Auth-Key ' . $this->apiKey,
  94.                     'Content-Type: application/x-www-form-urlencoded',
  95.                 ],
  96.                 http_build_query($params)
  97.             );
  98.  
  99.             return $result['translations'][0]['text'] ?? '';
  100.         }
  101. }
  102.  
  103. // ---------------------------------------------------------------------
  104. // Provider: Google Cloud Translation API v2
  105. // Target lang example: 'es', 'fr', 'de' (lowercase ISO 639-1)
  106. // ---------------------------------------------------------------------
  107. final class GoogleTranslateProvider implements TranslationProviderInterface
  108. {
  109.     private string $apiKey;
  110.     private string $endpoint = 'https://translation.googleapis.com/language/translate/v2';
  111.  
  112.     public function __construct(string $apiKey)
  113.     {
  114.         $this->apiKey = $apiKey;
  115.     }
  116.  
  117.     public function translate(string $text, string $targetLang, ?string $sourceLang = null): string
  118.     {
  119.         $params = [
  120.             'key' => $this->apiKey,
  121.             'q' => $text,
  122.             'target' => $targetLang,
  123.             'format' => 'text',
  124.         ];
  125.         if ($sourceLang !== null) {
  126.             $params['source'] = $sourceLang;
  127.         }
  128.  
  129.         $result = HttpClient::post(
  130.             $this->endpoint,
  131.             ['Content-Type: application/x-www-form-urlencoded'],
  132.             http_build_query($params)
  133.         );
  134.  
  135.         return $result['data']['translations'][0]['translatedText'] ?? '';
  136.     }
  137. }
  138.  
  139. // ---------------------------------------------------------------------
  140. // Provider: Microsoft Translator (Azure Cognitive Services)
  141. // Target lang example: 'es', 'fr', 'de'
  142. // ---------------------------------------------------------------------
  143. final class MicrosoftTranslatorProvider implements TranslationProviderInterface
  144. {
  145.     private string $apiKey;
  146.     private string $region;
  147.     private string $endpoint = 'https://api.cognitive.microsofttranslator.com/translate?api-version=3.0';
  148.  
  149.     public function __construct(string $apiKey, string $region)
  150.     {
  151.         $this->apiKey = $apiKey;
  152.         $this->region = $region;
  153.     }
  154.  
  155.     public function translate(string $text, string $targetLang, ?string $sourceLang = null): string
  156.     {
  157.         $url = $this->endpoint . '&to=' . urlencode($targetLang);
  158.         if ($sourceLang !== null) {
  159.             $url .= '&from=' . urlencode($sourceLang);
  160.         }
  161.  
  162.         $headers = [
  163.             'Ocp-Apim-Subscription-Key: ' . $this->apiKey,
  164.             'Ocp-Apim-Subscription-Region: ' . $this->region,
  165.             'Content-Type: application/json',
  166.         ];
  167.  
  168.         $body = json_encode([['Text' => $text]]);
  169.  
  170.         $result = HttpClient::post($url, $headers, $body);
  171.  
  172.         return $result[0]['translations'][0]['text'] ?? '';
  173.     }
  174. }
  175.  
  176. // ---------------------------------------------------------------------
  177. // Provider: LibreTranslate (self-hosted or public instance, no vendor lock-in)
  178. // Target lang example: 'es', 'fr', 'de'
  179. // ---------------------------------------------------------------------
  180. final class LibreTranslateProvider implements TranslationProviderInterface
  181. {
  182.     private string $endpoint;
  183.     private ?string $apiKey;
  184.  
  185.     public function __construct(string $endpoint = 'https://libretranslate.com/translate', ?string $apiKey = null)
  186.     {
  187.         $this->endpoint = $endpoint;
  188.         $this->apiKey = $apiKey;
  189.     }
  190.  
  191.     public function translate(string $text, string $targetLang, ?string $sourceLang = null): string
  192.     {
  193.         $payload = [
  194.             'q' => $text,
  195.             'source' => $sourceLang ?? 'auto',
  196.             'target' => $targetLang,
  197.             'format' => 'text',
  198.         ];
  199.         if ($this->apiKey !== null) {
  200.             $payload['api_key'] = $this->apiKey;
  201.         }
  202.  
  203.         $result = HttpClient::post(
  204.             $this->endpoint,
  205.             ['Content-Type: application/json'],
  206.             json_encode($payload)
  207.         );
  208.  
  209.         return $result['translatedText'] ?? '';
  210.     }
  211. }
  212.  
  213. // ---------------------------------------------------------------------
  214. // Facade: what your application code actually talks to
  215. // ---------------------------------------------------------------------
  216. final class Translator
  217. {
  218.     private TranslationProviderInterface $provider;
  219.  
  220.     public function __construct(TranslationProviderInterface $provider)
  221.     {
  222.         $this->provider = $provider;
  223.     }
  224.  
  225.     public function translate(string $text, string $targetLang, ?string $sourceLang = null): string
  226.     {
  227.         return $this->provider->translate($text, $targetLang, $sourceLang);
  228.     }
  229.  
  230.     /**
  231.      * Convenience for translating several strings in one call.
  232.      * (Loops client-side; providers with native batch endpoints could
  233.      * override this for efficiency.)
  234.      *
  235.      * @param string[] $texts
  236.      * @return string[]
  237.      */
  238.     public function translateBatch(array $texts, string $targetLang, ?string $sourceLang = null): array
  239.     {
  240.         $results = [];
  241.         foreach ($texts as $key => $text) {
  242.             $results[$key] = $this->translate($text, $targetLang, $sourceLang);
  243.         }
  244.         return $results;
  245.     }
  246. }
  247.  
  248. // ---------------------------------------------------------------------
  249. // Usage examples (uncomment the one you need)
  250. // ---------------------------------------------------------------------
  251.  
  252. // DeepL
  253. // $translator = new Translator(new DeepLProvider('YOUR_DEEPL_API_KEY'));
  254. // echo $translator->translate('Hello, world!', 'DE');
  255.  
  256. // Google Cloud Translation
  257. // $translator = new Translator(new GoogleTranslateProvider('YOUR_GOOGLE_API_KEY'));
  258. // echo $translator->translate('Hello, world!', 'es');
  259.  
  260. // Microsoft Translator
  261. // $translator = new Translator(new MicrosoftTranslatorProvider('YOUR_MS_KEY', 'YOUR_REGION'));
  262. // echo $translator->translate('Hello, world!', 'it');
  263.  
  264. // LibreTranslate (free/self-hosted, no API key required by default)
  265. // $translator = new Translator(new LibreTranslateProvider());
  266. // echo $translator->translate('Hello, world!', 'fr');
  267.  
  268. // Batch example
  269. // $translator = new Translator(new DeepLProvider('YOUR_DEEPL_API_KEY'));
  270. // $translated = $translator->translateBatch(
  271. //     ['Hello', 'Goodbye', 'Thank you'],
  272. //     'FR'
  273. // );
  274. // print_r($translated);
Advertisement
Add Comment
Please, Sign In to add comment