v3.0.0.2
FlatlyPage
- <?php
- header('Content-Type: application/json; charset=utf-8');
-
- if (isset($_SERVER['HTTP_ORIGIN'])) {
-
- $originHost = parse_url($_SERVER['HTTP_ORIGIN'], PHP_URL_HOST);
- $serverHost = $_SERVER['HTTP_HOST'];
- $serverParts = explode('.', $serverHost);
- $baseDomain = implode('.', array_slice($serverParts, -2));
-
- if (
- $originHost === $baseDomain ||
- str_ends_with($originHost, '.' . $baseDomain)
- ) {
- header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
- header('Access-Control-Allow-Credentials: true');
- header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
- header('Access-Control-Allow-Headers: Content-Type, Authorization');
- }
- }
-
- if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
- http_response_code(200);
- exit;
- }
-
- function logDebug($msg) {
- file_put_contents(__DIR__.'/translate_debug.log', date('Y-m-d H:i:s').' - '.$msg."\n", FILE_APPEND);
- }
-
- $xmlPath = __DIR__.'/../data/translate-api.xml';
- if (!file_exists($xmlPath)) {
- logDebug("ERROR: XML not found");
- http_response_code(500);
- die(json_encode(['error'=>'Config not found', 'path'=>$xmlPath]));
- }
-
- $xml = simplexml_load_file($xmlPath);
- $apis = [];
- foreach ($xml->apis->api as $api) {
- $apis[(string)$api->id] = [
- 'endpoint' => (string)$api->endpoint,
- 'apiKey' => (string)$api->apiKey,
- 'requiresKey' => ((string)$api->requiresKey==='true')
- ];
- }
-
- $systemFile = __DIR__.'/../data/system.php';
- $system = is_file($systemFile) ? include $systemFile : [];
- if (is_array($system) && !empty($system['translator_api_key']) && isset($apis[$system['translator_provider'] ?? ''])) {
- $apis[$system['translator_provider']]['apiKey'] = (string) $system['translator_api_key'];
- }
-
- $input = json_decode(file_get_contents('php://input'), true);
- $text = trim($input['text'] ?? '');
- $source = $input['source'] ?? 'auto';
- $target = $input['target'] ?? 'en';
- $provider = $input['provider'] ?? 'mymemory';
-
- if ($text === '') {
- http_response_code(400);
- die(json_encode(['error'=>'No text provided']));
- }
-
- if (!isset($apis[$provider])) {
- http_response_code(400);
- die(json_encode(['error'=>"Invalid provider: $provider"]));
- }
-
- $config = $apis[$provider];
- $translatedText = null;
-
- try {
- switch($provider) {
-
- case 'mymemory':
- $url = $config['endpoint'].'?q='.urlencode($text).'&langpair='.$source.'|'.$target;
- $resp = @file_get_contents($url);
- if (!$resp) throw new Exception('MyMemory connection failed');
- $data = json_decode($resp,true);
- $translatedText = $data['responseData']['translatedText'] ?? null;
- break;
-
- case 'google':
- if (empty($config['apiKey'])) throw new Exception('Google API key missing');
- $url = $config['endpoint'].'?key='.$config['apiKey'];
- $post = json_encode(['q'=>$text,'source'=>$source,'target'=>$target,'format'=>'text']);
- $opts = ['http'=>['method'=>'POST','header'=>'Content-Type: application/json','content'=>$post,'ignore_errors'=>true]];
- $resp = file_get_contents($url,false,stream_context_create($opts));
- $data = json_decode($resp,true);
- if (isset($data['error'])) throw new Exception($data['error']['message']);
- $translatedText = $data['data']['translations'][0]['translatedText'] ?? null;
- break;
-
- case 'deepl':
- if (empty($config['apiKey'])) throw new Exception('DeepL API key missing');
-
- $text = mb_substr($text, 0, 5000);
- $text = str_replace(["\0","\x1a"], '', $text);
-
- $postData = json_encode([
- 'text' => [$text],
- 'source_lang' => strtoupper($source),
- 'target_lang' => strtoupper($target)
- ]);
-
- $options = [
- 'http'=>[
- 'method'=>'POST',
- 'header'=>"Content-Type: application/json\r\n".
- "Authorization: DeepL-Auth-Key ".$config['apiKey'],
- 'content'=>$postData,
- 'timeout'=>30,
- 'ignore_errors'=>true
- ]
- ];
-
- $response = file_get_contents($config['endpoint'], false, stream_context_create($options));
- if ($response === false) throw new Exception('DeepL connection failed');
- $data = json_decode($response,true);
- if (isset($data['message'])) throw new Exception('DeepL error: '.$data['message']);
- $translatedText = $data['translations'][0]['text'] ?? null;
- break;
-
- case 'hf-marian':
- if (empty($config['apiKey'])) throw new Exception('HF API key missing');
-
- $modelPair = "{$source}-{$target}";
- $modelName = "Helsinki-NLP/opus-mt-" . $modelPair;
- $dynamicUrl = "https://router.huggingface.co/hf-inference/models/" . $modelName;
-
- $postData = json_encode(['inputs' => $text]);
- $options = [
- 'http' => [
- 'method' => 'POST',
- 'header' => "Content-Type: application/json\r\n" .
- "Authorization: Bearer " . $config['apiKey'] . "\r\n" .
- "X-Wait-For-Model: true\r\n",
- 'content' => $postData,
- 'timeout' => 60,
- 'ignore_errors' => true
- ]
- ];
-
- $response = @file_get_contents($dynamicUrl, false, stream_context_create($options));
- if ($response === false) {
- throw new Exception("Connection to model failed: $modelName");
- }
-
- $data = json_decode($response, true);
-
- if (isset($data['error'])) {
- if (strpos($data['error'], 'not found') !== false || strpos($data['error'], 'Model not found') !== false) {
- echo "[Error: The language pair $source to $target is not supported by this model]";
- exit;
- }
- if (isset($data['estimated_time'])) {
- throw new Exception("Model is loading. Try again in " . round($data['estimated_time']) . "s.");
- }
- throw new Exception('HF Error: ' . $data['error']);
- }
-
- $result = is_array($data) ? ($data[0] ?? $data) : $data;
-
- if (isset($result['translation_text'])) {
- $translatedText = $result['translation_text'];
- } elseif (isset($result['generated_text'])) {
- $translatedText = $result['generated_text'];
- } else {
- throw new Exception('HF translation failed: unexpected response format');
- }
- break;
-
-
- default:
- throw new Exception("Unknown provider: $provider");
- }
-
- if (!$translatedText) throw new Exception('No translation returned');
-
- echo json_encode([
- 'success'=>true,
- 'translatedText'=>$translatedText,
- 'provider'=>$provider,
- 'source'=>$source,
- 'target'=>$target
- ]);
-
- } catch(Exception $e) {
- logDebug("EXCEPTION: ".$e->getMessage());
- http_response_code(500);
- echo json_encode(['error'=>$e->getMessage()]);
- }
-