| Server IP : 188.114.96.3 / Your IP : 216.73.216.143 Web Server : Apache System : Linux sv058.home.net.pl 6.8.2 husak_dirty_pages_fix #1 SMP PREEMPT_DYNAMIC Tue Apr 2 22:06:51 CEST 2024 x86_64 User : ( 3194769) PHP Version : 8.5.12 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /polana/includes/ |
Upload File : |
<?php
declare(strict_types=1);
// KONFIGURACJA jest w osobnym, niepublikowanym pliku .local.php (nie jest częścią paczki).
if (is_file(__DIR__.'/polana_translate_config.local.php')) {
require_once __DIR__.'/polana_translate_config.local.php';
}
function polana_mt_configured(): bool
{
return defined('POLANA_MT_ENDPOINT') && defined('POLANA_MT_TOKEN') &&
is_string(POLANA_MT_TOKEN) && strlen(POLANA_MT_TOKEN) >= 24 &&
is_string(POLANA_MT_ENDPOINT) && str_starts_with(POLANA_MT_ENDPOINT, 'https://');
}
/** Tłumaczy wyłącznie tekst z zatwierdzonej karty; bez cen i bez HTML. */
function polana_mt_batch(array $texts): array
{
if (!polana_mt_configured()) {
throw new RuntimeException('Brak konfiguracji LibreTranslate (includes/polana_translate_config.local.php).');
}
if (!function_exists('curl_init')) {
throw new RuntimeException('Hosting PHP nie posiada rozszerzenia cURL (potrzebnego do połączenia z Dockerem).');
}
if (!$texts || count($texts) > 5) throw new RuntimeException('Partia tłumaczeń ma nieprawidłowy rozmiar.');
foreach ($texts as $txt) {
if (!is_string($txt) || trim($txt) === '' || strlen($txt) > 1500) {
throw new RuntimeException('Tekst do przetłumaczenia jest nieprawidłowy lub zbyt długi.');
}
}
$url = POLANA_MT_ENDPOINT;
if (parse_url($url, PHP_URL_SCHEME) !== 'https' || parse_url($url, PHP_URL_USER)) {
throw new RuntimeException('Adres API tłumaczeń musi używać HTTPS.');
}
$body = json_encode(['q'=>array_values($texts), 'source'=>'pl', 'target'=>'en', 'format'=>'text'], JSON_THROW_ON_ERROR|JSON_UNESCAPED_UNICODE);
$curl = curl_init($url);
$opts = [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Accept: application/json',
'X-TKLM-Translate-Key: '.POLANA_MT_TOKEN,
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 6,
CURLOPT_TIMEOUT => 25,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_MAXREDIRS => 0,
];
if (defined('CURLOPT_PROTOCOLS_STR')) $opts[CURLOPT_PROTOCOLS_STR] = 'https';
elseif (defined('CURLOPT_PROTOCOLS') && defined('CURLPROTO_HTTPS')) $opts[CURLOPT_PROTOCOLS] = CURLPROTO_HTTPS;
curl_setopt_array($curl, $opts);
try {
$response = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$error = curl_error($curl);
} finally {
curl_close($curl);
}
if (!is_string($response) || $status !== 200) {
throw new RuntimeException('Błąd serwera tłumaczeń, HTTP '.$status.'. '.$error.' Sprawdź kontener, proxy i token API.');
}
$data = json_decode($response, true);
$translated = $data['translatedText'] ?? null;
if (count($texts) === 1 && is_string($translated)) $translated = [$translated];
if (!is_array($translated) || count($translated) !== count($texts)) {
throw new RuntimeException('Serwer tłumaczeń zwrócił nieprawidłową liczbę wyników.');
}
$out = [];
foreach ($translated as $value) {
if (!is_string($value) || trim($value) === '' || strlen($value) > 2500) {
throw new RuntimeException('Pusta lub nieprawidłowa odpowiedź z tłumaczenia.');
}
$out[] = trim($value);
}
return $out;
}
/** Translate longer plain-text website fields in small bounded requests. */
function polana_mt_long_text(string $source): string
{
$source = trim($source);
if ($source === '' || strlen($source) > 20000) {
throw new RuntimeException('Tekst musi mieć od 1 do 20000 bajtów UTF-8.');
}
$paragraphs = preg_split('/(\R+)/u', $source, -1, PREG_SPLIT_DELIM_CAPTURE);
if (!is_array($paragraphs)) throw new RuntimeException('Nieprawidłowe kodowanie UTF-8.');
$parts = [];
foreach ($paragraphs as $para) {
if (preg_match('/^\R+$/u', $para)) { $parts[]=['newline'=>$para]; continue; }
$tokens = preg_split('/(?<=\s)|(?=\s)/u', $para, -1, PREG_SPLIT_NO_EMPTY);
if (!is_array($tokens)) throw new RuntimeException('Błędny tekst UTF-8.');
$current = '';
foreach ($tokens as $token) {
if (strlen($token) > 1100) throw new RuntimeException('Pojedynczy fragment tekstu jest za długi.');
if (strlen($current.$token) > 1100 && trim($current) !== '') {
$parts[]=['text'=>trim($current)];
$current = '';
}
$current.=$token;
}
if (trim($current) !== '') $parts[]=['text'=>trim($current)];
}
$indexes=[]; $texts=[];
foreach ($parts as $i=>$part) if(isset($part['text'])) {$indexes[]=$i;$texts[]=$part['text'];}
foreach (array_chunk($texts,5,true) as $group) {
$translated=polana_mt_batch(array_values($group));
foreach (array_keys($group) as $j=>$index) {
$at=$indexes[$index];
$parts[$at]['translated']=$translated[$j];
}
}
$result=''; $priorWasText=false;
foreach ($parts as $part) {
if(isset($part['newline'])) {$result.=$part['newline'];$priorWasText=false;}
else {
if($priorWasText)$result.=' ';
$result.=$part['translated'];$priorWasText=true;
}
}
return trim($result);
}