| 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/admin/ |
Upload File : |
<?php
declare(strict_types=1);
require_once dirname(__DIR__).'/includes/functions.php';
require_admin_role();
require_once dirname(__DIR__).'/includes/tklm_v9.php';
require_once dirname(__DIR__).'/includes/polana_v14_names.php';
v9_init();
$error='';$notice='';
if(($_SERVER['REQUEST_METHOD']??'')==='POST'){
verify_csrf();
try{
$action=(string)($_POST['action']??'');
if($action==='bulk'){
$ids=$_POST['ids']??[];
if(!is_array($ids))throw new RuntimeException('Nieprawidłowa lista');
$ids=array_values(array_unique(array_filter(array_map('intval',$ids),static fn($v)=>$v>0)));
if(count($ids)>100)throw new RuntimeException('Maksymalnie 100 na operację');
$get=db()->prepare("SELECT id,field,status FROM tklm_v9_jobs WHERE id=? AND entity IN ('menu_items','menu_categories')");
$set=db()->prepare("UPDATE tklm_v9_jobs SET translated_text=? WHERE id=? AND status='review' AND entity IN ('menu_items','menu_categories')");
$ok=0;$bad=[];
foreach($ids as $id){
try{
$get->execute([$id]);$job=$get->fetch(PDO::FETCH_ASSOC);
if(!$job||$job['status']!=='review')throw new RuntimeException('Nie jest gotowe do zatwierdzenia');
$new=(string)(($_POST['translation']??[])[$id]??'');
$new=trim($new);
if($new===''||mb_strlen($new,'UTF-8')>6000||($job['field']==='name'&&mb_strlen($new,'UTF-8')>255))throw new RuntimeException('Pusty lub zbyt długi tekst');
$set->execute([$new,$id]);
v9_approve($id);
$ok++;
}catch(Throwable $e){$bad[]=$id.': '.$e->getMessage();}
}
$notice='Zatwierdzono '.$ok.'; błędów '.count($bad).($bad?' ('.implode('; ',array_slice($bad,0,4)).')':'');
}elseif($action==='retry'){
$id=(int)($_POST['id']??0);
$q=db()->prepare("UPDATE tklm_v9_jobs SET status='pending',attempts=0,last_error=NULL WHERE id=? AND entity IN ('menu_items','menu_categories') AND status='review'");
$q->execute([$id]);$notice=$q->rowCount()?'Dodano do ponownego tłumaczenia':'Nie znaleziono pozycji';
}
}catch(Throwable $e){$error=$e->getMessage();}
}
$q=db()->query("SELECT id,entity,entity_id,field,lang,source_text,translated_text,status FROM tklm_v9_jobs WHERE entity IN ('menu_items','menu_categories') AND status='review' ORDER BY id DESC LIMIT 100");
$jobs=$q->fetchAll(PDO::FETCH_ASSOC);
render_admin_header('Polana — poprawki tłumaczeń menu');
?>
<main style="max-width:1150px;margin:24px auto;padding:16px">
<h1>Menu — popraw tłumaczenia i zatwierdź zbiorczo</h1>
<p>Popraw każdy tekst w polu, zaznacz pozycje i zatwierdź. Wszystkie wprowadzone zmiany zostaną zapisane przed akceptacją.</p>
<p><a href="/admin/polana-v14-slownik.php">Słownik nazw własnych</a> · <a href="/admin/v9-review.php">Uruchom tłumaczenie kolejki menu</a></p>
<?php if($error):?><p style="color:#a22"><?=htmlspecialchars($error,ENT_QUOTES,'UTF-8')?></p><?php endif;?>
<?php if($notice):?><p style="color:#275d30"><?=htmlspecialchars($notice,ENT_QUOTES,'UTF-8')?></p><?php endif;?>
<form method="post" id="v14menu">
<?=csrf_field()?><input type="hidden" name="action" value="bulk">
<div style="position:sticky;top:0;background:white;padding:13px;z-index:2;border:1px solid #ddd;border-radius:10px;display:flex;gap:16px;align-items:center;flex-wrap:wrap">
<label><input type="checkbox" id="all"> Zaznacz gotowe</label><span id="count">0 wybranych</span>
<button type="submit" onclick="return confirm('Zapisać korekty i zatwierdzić zaznaczone tłumaczenia?')" style="padding:10px 15px">Zapisz korekty i zatwierdź zaznaczone</button>
</div>
<?php foreach($jobs as $j): ?>
<section style="border:1px solid #ddd;border-radius:10px;padding:16px;margin:12px 0;background:#fff">
<label><input type="checkbox" class="pick" name="ids[]" value="<?=(int)$j['id']?>"> <b><?=htmlspecialchars(strtoupper($j['lang']).' • '.$j['entity'].' #'.$j['entity_id'].' • '.$j['field'],ENT_QUOTES,'UTF-8')?></b></label>
<p><strong>Polski:</strong> <?=nl2br(htmlspecialchars((string)$j['source_text'],ENT_QUOTES,'UTF-8'))?></p>
<?php $missing=p14_missing_terms((string)$j['source_text'],(string)$j['translated_text']);if($missing):?>
<p style="color:#a54e06">Uwaga: nazwa własna może być zmieniona: <?=htmlspecialchars(implode(', ',$missing),ENT_QUOTES,'UTF-8')?>. Popraw tekst lub przetłumacz ponownie.</p><?php endif;?>
<label><strong>Tłumaczenie do edycji</strong>
<textarea name="translation[<?=(int)$j['id']?>]" rows="3" style="width:100%;padding:10px;border:1px solid #ddd;border-radius:7px"><?=htmlspecialchars((string)$j['translated_text'],ENT_QUOTES,'UTF-8')?></textarea></label>
<button type="submit" form="retry_<?=(int)$j['id']?>">Ponów tłumaczenie z ochroną nazw</button>
</section>
<?php endforeach;?>
<?php if(!$jobs):?><p>Brak gotowych tłumaczeń menu.</p><?php endif;?>
</form>
<?php foreach($jobs as $j):?>
<form id="retry_<?=(int)$j['id']?>" method="post"><?=csrf_field()?><input type="hidden" name="action" value="retry"><input type="hidden" name="id" value="<?=(int)$j['id']?>"></form>
<?php endforeach;?>
<script>
(()=>{const items=[...document.querySelectorAll('.pick')],all=document.querySelector('#all'),label=document.querySelector('#count');
function refresh(){const n=items.filter(x=>x.checked).length;label.textContent=n+' wybranych';all.checked=n>0&&n===items.length;all.indeterminate=n>0&&n<items.length;}
all.addEventListener('change',()=>{items.forEach(x=>x.checked=all.checked);refresh()});items.forEach(x=>x.addEventListener('change',refresh));refresh();})();
</script>
</main>
<?php render_admin_footer(); ?>