Lines 94.17% 97 / 103
Methods 66.66% 6 / 9
Classes 0.00% 0 / 1
Covered by tests of size
Name Lines Methods CRAP
 getProviderName 100.00% 1 / 1 100.00% 1 / 1 1
 doTranslate 100.00% 19 / 19 100.00% 1 / 1 6
 doTranslateBatch 86.95% 20 / 23 0.00% 0 / 1 6.08
 translateBatch 66.66% 2 / 3 0.00% 0 / 1 2.15
 supportsLanguagePair 100.00% 1 / 1 100.00% 1 / 1 1
 getSupportedLanguages 100.00% 43 / 43 100.00% 1 / 1 1
 mapLanguageCode 60.00% 3 / 5 0.00% 0 / 1 6.60
 [phpMyFAQ\Translation\AbstractTranslationProvider] __construct 100.00% 1 / 1 100.00% 1 / 1 1
 [phpMyFAQ\Translation\AbstractTranslationProvider] translate 100.00% 7 / 7 100.00% 1 / 1 3
32class GoogleTranslationProvider extends AbstractTranslationProvider
33{
34    private const string API_URL = 'https://translation.googleapis.com/language/translate/v2';
35
36    /**
37     * @inheritDoc
38     */
39    public function getProviderName(): string
40    {
41        return 'Google Cloud Translation';
42    }
43
44    /**
45     * @inheritDoc
46     */
47    protected function doTranslate(string $text, string $sourceLang, string $targetLang): string
48    {
49        $apiKey = $this->configuration->get('translation.googleApiKey');
50
51        if ((string) $apiKey === '') {
52            throw new ApiException('Google Cloud Translation API key not configured');
53        }
54
55        try {
56            $response = $this->httpClient->request('POST', self::API_URL, [
57                'query' => ['key' => $apiKey],
58                'json' => [
59                    'q' => $text,
60                    'source' => $this->mapLanguageCode($sourceLang),
61                    'target' => $this->mapLanguageCode($targetLang),
62                    'format' => 'text',
63                ],
64            ]);
65
66            $data = $response->toArray();
67            $payload = $data['data'] ?? [];
68            $translations = is_array($payload) ? $payload['translations'] ?? [] : [];
69            $firstTranslation = is_array($translations) ? $translations[0] ?? [] : [];
70
71            return is_array($firstTranslation) ? (string) ($firstTranslation['translatedText'] ?? '') : '';
72        } catch (Exception|TransportExceptionInterface $e) {
73            throw new ApiException('Google Translation API error: ' . $e->getMessage());
74        }
75    }
76
77    /**
78     * @inheritDoc
79     */
80    protected function doTranslateBatch(array $texts, string $sourceLang, string $targetLang): array
81    {
82        $apiKey = $this->configuration->get('translation.googleApiKey');
83
84        if ((string) $apiKey === '') {
85            throw new ApiException('Google Cloud Translation API key not configured');
86        }
87
88        try {
89            $response = $this->httpClient->request('POST', self::API_URL, [
90                'query' => ['key' => $apiKey],
91                'json' => [
92                    'q' => $texts,
93                    'source' => $this->mapLanguageCode($sourceLang),
94                    'target' => $this->mapLanguageCode($targetLang),
95                    'format' => 'text',
96                ],
97            ]);
98
99            $data = $response->toArray();
100            $payload = $data['data'] ?? [];
101            $translations = is_array($payload) ? $payload['translations'] ?? [] : [];
102
103            return array_map(
104                static fn(mixed $translation): string => is_array($translation)
105                    ? (string) ($translation['translatedText'] ?? '')
106                    : '',
107                is_array($translations) ? array_values($translations) : [],
108            );
109        } catch (Exception|TransportExceptionInterface $e) {
110            throw new ApiException('Google Translation API error: ' . $e->getMessage());
111        }
112    }
113
114    /**
115     * @inheritDoc
116     */
117    public function translateBatch(
118        array $texts,
119        string $sourceLang,
120        string $targetLang,
121        bool $preserveHtml = false,
122    ): array {
123        if ($preserveHtml) {
124            // Process each text individually with HTML preservation
125            return array_map(fn($text) => $this->translate($text, $sourceLang, $targetLang, true), $texts);
126        }
127
128        return $this->doTranslateBatch($texts, $sourceLang, $targetLang);
129    }
130
131    /**
132     * @inheritDoc
133     */
134    public function supportsLanguagePair(string $sourceLang, string $targetLang): bool
135    {
136        // Google Cloud Translation supports most language pairs
137        return true;
138    }
139
140    /**
141     * @inheritDoc
142     */
143    public function getSupportedLanguages(): array
144    {
145        // Common languages supported by Google Cloud Translation
146        return [
147            'ar',
148            'bn',
149            'bs',
150            'cs',
151            'cy',
152            'da',
153            'de',
154            'el',
155            'en',
156            'es',
157            'eu',
158            'fa',
159            'fi',
160            'fr',
161            'he',
162            'hi',
163            'hu',
164            'id',
165            'it',
166            'ja',
167            'ko',
168            'lt',
169            'lv',
170            'mn',
171            'ms',
172            'nb',
173            'nl',
174            'pl',
175            'pt',
176            'ro',
177            'ru',
178            'sk',
179            'sl',
180            'sr',
181            'sv',
182            'th',
183            'tr',
184            'uk',
185            'ur',
186            'vi',
187            'zh',
188        ];
189    }
190
191    /**
192     * @inheritDoc
193     */
194    protected function mapLanguageCode(string $pmfLangCode): string
195    {
196        // Google uses standard ISO 639-1, with special cases
197        return match ($pmfLangCode) {
198            'zh' => 'zh-CN',
199            'pt' => 'pt-BR',
200            'nb' => 'no',
201            default => $pmfLangCode,
202        };
203    }
204}

Inherited from phpMyFAQ\Translation\AbstractTranslationProvider

41    public function __construct(
42        protected readonly Configuration $configuration,
43        protected readonly HttpClientInterface $httpClient,
44    ) {
45        $this->htmlPreserver = new HtmlPreserver();
46    }
58    public function translate(string $text, string $sourceLang, string $targetLang, bool $preserveHtml = false): string
59    {
60        if ($text === '') {
61            return '';
62        }
63
64        if ($preserveHtml) {
65            [$textWithPlaceholders, $htmlMap] = $this->htmlPreserver->replaceTags($text);
66            $translated = $this->doTranslate($textWithPlaceholders, $sourceLang, $targetLang);
67            return $this->htmlPreserver->restoreTags($translated, $htmlMap);
68        }
69
70        return $this->doTranslate($text, $sourceLang, $targetLang);
71    }