Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
AbstractTranslationProvider
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
2 / 2
4
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 translate
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
 doTranslate
n/a
0 / 0
n/a
0 / 0
0
 doTranslateBatch
n/a
0 / 0
n/a
0 / 0
0
 mapLanguageCode
n/a
0 / 0
n/a
0 / 0
0
1<?php
2
3declare(strict_types=1);
4
5/**
6 * Abstract base class for translation providers.
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public License,
9 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
10 * obtain one at https://mozilla.org/MPL/2.0/.
11 *
12 * @package   phpMyFAQ
13 * @author    Thorsten Rinne <thorsten@phpmyfaq.de>
14 * @copyright 2026 phpMyFAQ Team
15 * @license   http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
16 * @link      https://www.phpmyfaq.de
17 * @since     2026-01-17
18 */
19
20namespace phpMyFAQ\Translation;
21
22use phpMyFAQ\Configuration;
23use phpMyFAQ\Translation\Exception\TranslationException;
24use Symfony\Contracts\HttpClient\HttpClientInterface;
25
26/**
27 * Class AbstractTranslationProvider
28 *
29 * Base class providing common translation logic with HTML preservation support.
30 */
31abstract class AbstractTranslationProvider implements TranslationProviderInterface
32{
33    protected HtmlPreserver $htmlPreserver;
34
35    /**
36     * Constructor.
37     *
38     * @param Configuration $configuration phpMyFAQ configuration
39     * @param HttpClientInterface $httpClient HTTP client for API requests
40     */
41    public function __construct(
42        protected readonly Configuration $configuration,
43        protected readonly HttpClientInterface $httpClient,
44    ) {
45        $this->htmlPreserver = new HtmlPreserver();
46    }
47
48    /**
49     * Translate text with optional HTML preservation.
50     *
51     * @param string $text Text to translate
52     * @param string $sourceLang Source language code
53     * @param string $targetLang Target language code
54     * @param bool $preserveHtml Whether to preserve HTML tags
55     * @return string Translated text
56     * @throws TranslationException
57     */
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    }
72
73    /**
74     * Provider-specific translation implementation.
75     *
76     * @param string $text Text to translate (without HTML placeholders if preserveHtml was true)
77     * @param string $sourceLang Source language code
78     * @param string $targetLang Target language code
79     * @return string Translated text
80     * @throws TranslationException
81     */
82    abstract protected function doTranslate(string $text, string $sourceLang, string $targetLang): string;
83
84    /**
85     * Provider-specific batch translation implementation.
86     *
87     * @param array<string> $texts Texts to translate
88     * @param string $sourceLang Source language code
89     * @param string $targetLang Target language code
90     * @return array<string> Translated texts
91     * @throws TranslationException
92     */
93    abstract protected function doTranslateBatch(array $texts, string $sourceLang, string $targetLang): array;
94
95    /**
96     * Map phpMyFAQ language codes to provider-specific codes.
97     *
98     * @param string $pmfLangCode phpMyFAQ language code (e.g., 'en', 'de', 'zh')
99     * @return string Provider-specific language code
100     */
101    abstract protected function mapLanguageCode(string $pmfLangCode): string;
102}