| 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);
require_once __DIR__.'/functions.php';
require_once __DIR__.'/TklmTranslateClient.php';
function v9_init(): void {
db()->exec("CREATE TABLE IF NOT EXISTS tklm_v9_jobs (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
entity VARCHAR(32) NOT NULL, entity_id BIGINT UNSIGNED NOT NULL,
field VARCHAR(32) NOT NULL, lang CHAR(2) NOT NULL,
source_hash CHAR(64) NOT NULL, source_text MEDIUMTEXT NOT NULL,
translated_text MEDIUMTEXT NULL, status VARCHAR(20) NOT NULL DEFAULT 'pending',
attempts INT NOT NULL DEFAULT 0, last_error VARCHAR(500) NULL,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uq_job(entity,entity_id,field,lang), KEY ix_status(status,updated_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
}
function v9_enqueue(string $entity,int $id,string $field,string $lang,string $value): void {
$value=trim($value); if($value==='')return;
$hash=hash('sha256',$value);
$q=db()->prepare("INSERT INTO tklm_v9_jobs(entity,entity_id,field,lang,source_hash,source_text,status)
VALUES(?,?,?,?,?,?,'pending') ON DUPLICATE KEY UPDATE
status=IF(source_hash=VALUES(source_hash),status,'pending'),
translated_text=IF(source_hash=VALUES(source_hash),translated_text,NULL),
attempts=IF(source_hash=VALUES(source_hash),attempts,0),
source_text=VALUES(source_text),source_hash=VALUES(source_hash)");
$q->execute([$entity,$id,$field,$lang,$hash,$value]);
}
function v9_scan(): int {
$count=0;
$spec=[
'menu_categories'=>['name'],
'menu_items'=>['name','description','allergens'],
'blog_posts'=>['title','excerpt','content']
];
foreach($spec as $table=>$fields){
$cols=implode(',',array_merge(['id'],$fields,array_merge(...array_map(fn($f)=>array_map(fn($l)=>$f.'_'.$l,['en','de','es']),$fields))));
foreach(db()->query("SELECT $cols FROM $table") as $row){
foreach($fields as $field){
foreach(['en','de','es'] as $lang){
if(trim((string)($row[$field.'_'.$lang]??''))==='') v9_enqueue($table,(int)$row['id'],$field,$lang,(string)($row[$field]??''));
$count++;
}
}
}
}
return $count;
}
function v9_resolve_translate_key(): string {
$host=strtolower(preg_replace('/:\\d+$/','',(string)($_SERVER['HTTP_HOST']??'mojapolanasmakow.pl')));
$host=preg_replace('/^www\\./','',$host);
if(!in_array($host,['mojapolanasmakow.pl','polanasmakow.pl'],true))$host='mojapolanasmakow.pl';
$paths=[
dirname(__DIR__,2).'/tklm-translate-private/keys.php',
dirname(__DIR__).'/tklm-translate-private/keys.php'
];
$v=getenv('TKLM_TRANSLATE_KEY');
if(is_string($v)&&preg_match('/^[a-f0-9]{48}$/i',trim($v)))return strtolower(trim($v));
foreach($paths as $path){
if(!is_file($path)||!is_readable($path))continue;
$keys=require $path;
if(!is_array($keys))continue;
foreach([$host,'mojapolanasmakow.pl','polanasmakow.pl'] as $domain){
$key=$keys[$domain]??'';
if(is_string($key)&&preg_match('/^[a-f0-9]{48}$/i',trim($key)))return strtolower(trim($key));
}
}
throw new RuntimeException('Klucz: nie znaleziono prawidlowego wpisu domenowego w prywatnym keys.php (katalog NAD webroot).');
}
function v9_work(int $limit=8): array {
$key=v9_resolve_translate_key();
if(!$key)throw new RuntimeException('Nie znaleziono klucza API. Sprawdz tklm-translate-private/keys.php (bez ujawniania wartosci).');
$api=new TklmTranslateClient($key);
$allowed=['menu_categories'=>['name'],'menu_items'=>['name','description','allergens'],'blog_posts'=>['title','excerpt','content']];
$results=[];
$jobs=db()->query("SELECT * FROM tklm_v9_jobs WHERE status='pending' AND attempts<5 ORDER BY updated_at,id LIMIT ".max(1,min(20,$limit)))->fetchAll(PDO::FETCH_ASSOC);
foreach($jobs as $job){
$table=$job['entity'];$field=$job['field'];$lang=$job['lang'];
if(!isset($allowed[$table])||!in_array($field,$allowed[$table],true)||!in_array($lang,['en','de','es'],true))continue;
$current=db()->prepare("SELECT `$field` FROM `$table` WHERE id=?");
$current->execute([$job['entity_id']]);
$source=$current->fetchColumn();
if(!is_string($source)||hash('sha256',trim($source))!==$job['source_hash']){v9_enqueue($table,(int)$job['entity_id'],$field,$lang,(string)$source);continue;}
try {
if(strlen($source)>45000)throw new RuntimeException('Tekst przekracza limit; podziel artykul na fragmenty');
$answer=$api->translate($source,'pl',$lang);
$translated=trim((string)($answer['translatedText']??''));
if($translated==='')throw new RuntimeException('Puste tlumaczenie');
$q=db()->prepare("UPDATE tklm_v9_jobs SET translated_text=?,status='review',last_error=NULL WHERE id=? AND source_hash=?");
$q->execute([$translated,$job['id'],$job['source_hash']]);
$results[]='OK '.$job['id'];
} catch(Throwable $e){
$q=db()->prepare("UPDATE tklm_v9_jobs SET attempts=attempts+1,last_error=?,updated_at=NOW() WHERE id=?");
$q->execute([substr($e->getMessage(),0,500),$job['id']]);
$results[]='ERROR '.$job['id'];
}
}
return $results;
}
function v9_approve(int $jobId): void {
$q=db()->prepare("SELECT * FROM tklm_v9_jobs WHERE id=? AND status='review'");
$q->execute([$jobId]);$j=$q->fetch(PDO::FETCH_ASSOC);
if(!$j)throw new RuntimeException('Brak zadania do zatwierdzenia');
$allowed=['menu_categories'=>['name'],'menu_items'=>['name','description','allergens'],'blog_posts'=>['title','excerpt','content']];
$table=$j['entity'];$field=$j['field'];$lang=$j['lang'];
if(!isset($allowed[$table])||!in_array($field,$allowed[$table],true)||!in_array($lang,['en','de','es'],true))throw new RuntimeException('Nieprawidlowe pole');
db()->beginTransaction();
try {
$q=db()->prepare("SELECT `$field` FROM `$table` WHERE id=? FOR UPDATE");$q->execute([$j['entity_id']]);
$current=$q->fetchColumn();
if(!is_string($current)||hash('sha256',trim($current))!==$j['source_hash'])throw new RuntimeException('Oryginal zmienil sie; ponow tlumaczenie');
$target=$field.'_'.$lang;
$q=db()->prepare("UPDATE `$table` SET `$target`=? WHERE id=?");$q->execute([$j['translated_text'],$j['entity_id']]);
$q=db()->prepare("UPDATE tklm_v9_jobs SET status='approved' WHERE id=?");$q->execute([$jobId]);
db()->commit();
}catch(Throwable $e){db()->rollBack();throw $e;}
}
function v9_enqueue_blog_post(int $id): int {
$q=db()->prepare("SELECT id,title,excerpt,content FROM blog_posts WHERE id=?");$q->execute([$id]);
$row=$q->fetch(PDO::FETCH_ASSOC);if(!$row)return 0;
$n=0;
foreach(['title','excerpt','content'] as $field){
foreach(['en','de','es'] as $lang){
v9_enqueue('blog_posts',$id,$field,$lang,(string)($row[$field]??''));$n++;
}
}
return $n;
}