fixed newsletyter1
This commit is contained in:
+96
-53
@@ -167,9 +167,15 @@ try {
|
||||
SET title = ?, subject = ?, preheader = ?, blocks = ?, settings = ?,
|
||||
revision = revision + 1, updated_by = ?, updated_at = NOW()
|
||||
WHERE iddraft = ? AND deleted_at IS NULL" . ($force ? '' : ' AND revision = ?');
|
||||
$params = [$c['title'], $c['subject'], $c['preheader'],
|
||||
json_encode($c['blocks'], JSON_UNESCAPED_UNICODE), json_encode($c['settings'], JSON_UNESCAPED_UNICODE),
|
||||
$userId, $id];
|
||||
$params = [
|
||||
$c['title'],
|
||||
$c['subject'],
|
||||
$c['preheader'],
|
||||
json_encode($c['blocks'], JSON_UNESCAPED_UNICODE),
|
||||
json_encode($c['settings'], JSON_UNESCAPED_UNICODE),
|
||||
$userId,
|
||||
$id
|
||||
];
|
||||
if (!$force) $params[] = $rev;
|
||||
|
||||
$st = $pdo->prepare($sql);
|
||||
@@ -178,7 +184,9 @@ try {
|
||||
$d = draftRow($pdo, $id);
|
||||
if ($st->rowCount() === 0) {
|
||||
fail('Questa newsletter è stata salvata da un\'altra parte (un\'altra scheda o un altro computer).', 409, [
|
||||
'conflict' => true, 'revision' => (int) $d['revision'], 'updated_at' => $d['updated_at'],
|
||||
'conflict' => true,
|
||||
'revision' => (int) $d['revision'],
|
||||
'updated_at' => $d['updated_at'],
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -251,67 +259,93 @@ try {
|
||||
case 'upload_image':
|
||||
if (!$isPost) fail('Metodo non consentito.', 405);
|
||||
$f = $_FILES['image'] ?? null;
|
||||
if (!$f || $f['error'] !== UPLOAD_ERR_OK) fail('Caricamento non riuscito.');
|
||||
if (!$f || ($f['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) {
|
||||
$why = [
|
||||
UPLOAD_ERR_INI_SIZE => 'il file supera il limite del server (upload_max_filesize)',
|
||||
UPLOAD_ERR_FORM_SIZE => 'il file è troppo grande',
|
||||
UPLOAD_ERR_PARTIAL => 'caricamento interrotto',
|
||||
UPLOAD_ERR_NO_FILE => 'nessun file ricevuto',
|
||||
UPLOAD_ERR_NO_TMP_DIR => 'manca la cartella temporanea sul server',
|
||||
UPLOAD_ERR_CANT_WRITE => 'il server non riesce a scrivere il file',
|
||||
][$f['error'] ?? UPLOAD_ERR_NO_FILE] ?? 'errore sconosciuto';
|
||||
fail('Caricamento non riuscito: ' . $why . '.');
|
||||
}
|
||||
if ($f['size'] > 15 * 1024 * 1024) fail('Immagine troppo grande (massimo 15 MB).');
|
||||
|
||||
$info = @getimagesize($f['tmp_name']);
|
||||
$mime = $info['mime'] ?? '';
|
||||
if (!in_array($mime, ['image/jpeg', 'image/png', 'image/gif', 'image/webp'], true)) {
|
||||
fail('Formato non supportato: usa JPG, PNG, GIF o WebP.');
|
||||
}
|
||||
$ext = ['image/jpeg' => 'jpg', 'image/png' => 'png', 'image/gif' => 'gif', 'image/webp' => 'webp'][$mime] ?? null;
|
||||
if (!$ext) fail('Formato non supportato: usa JPG, PNG, GIF o WebP.');
|
||||
|
||||
$dirRel = 'assets/uploads/newsletter/' . date('Y/m');
|
||||
$dirAbs = __DIR__ . '/' . $dirRel;
|
||||
if (!is_dir($dirAbs) && !mkdir($dirAbs, 0755, true)) fail('Impossibile creare la cartella delle immagini.', 500);
|
||||
if (!is_dir($dirAbs) && !@mkdir($dirAbs, 0755, true)) {
|
||||
fail('Impossibile creare la cartella ' . $dirRel . ': controlla i permessi di assets/uploads.', 500);
|
||||
}
|
||||
if (!is_writable($dirAbs)) fail('La cartella ' . $dirRel . ' non è scrivibile: controlla i permessi.', 500);
|
||||
|
||||
$name = date('Ymd_His') . '_' . bin2hex(random_bytes(4));
|
||||
[$w, $h] = $info;
|
||||
$note = '';
|
||||
|
||||
if ($mime === 'image/gif') {
|
||||
// Le GIF possono essere animate: le teniamo come sono
|
||||
$file = $name . '.gif';
|
||||
move_uploaded_file($f['tmp_name'], $dirAbs . '/' . $file);
|
||||
// Si può ottimizzare? Serve GD con il formato giusto
|
||||
$reader = ['image/jpeg' => 'imagecreatefromjpeg', 'image/png' => 'imagecreatefrompng', 'image/webp' => 'imagecreatefromwebp'][$mime] ?? null;
|
||||
$canResize = $mime !== 'image/gif' && $reader && function_exists($reader) && function_exists('imagecreatetruecolor');
|
||||
|
||||
if (!$canResize) {
|
||||
// GIF (forse animata) oppure server senza GD: salviamo l'originale
|
||||
if ($mime !== 'image/gif' && $f['size'] > 3 * 1024 * 1024) {
|
||||
fail('Il server non può ridimensionare le immagini (manca la libreria GD) e questa supera 3 MB: riducila prima di caricarla.');
|
||||
}
|
||||
$file = $name . '.' . $ext;
|
||||
if (!move_uploaded_file($f['tmp_name'], $dirAbs . '/' . $file)) fail('Impossibile salvare l\'immagine.', 500);
|
||||
if ($mime !== 'image/gif') $note = 'Caricata senza ottimizzazione (sul server manca la libreria GD).';
|
||||
} else {
|
||||
$src = match ($mime) {
|
||||
'image/jpeg' => imagecreatefromjpeg($f['tmp_name']),
|
||||
'image/png' => imagecreatefrompng($f['tmp_name']),
|
||||
'image/webp' => imagecreatefromwebp($f['tmp_name']),
|
||||
};
|
||||
if (!$src) fail('Immagine non leggibile.');
|
||||
try {
|
||||
@ini_set('memory_limit', '512M'); // le foto dal telefono sono grandi
|
||||
$src = @$reader($f['tmp_name']);
|
||||
if (!$src) fail('Immagine non leggibile o danneggiata.');
|
||||
|
||||
// Foto dal telefono: raddrizza secondo l'orientamento EXIF
|
||||
if ($mime === 'image/jpeg' && function_exists('exif_read_data')) {
|
||||
$o = (int) (@exif_read_data($f['tmp_name'])['Orientation'] ?? 1);
|
||||
$rot = [3 => 180, 6 => -90, 8 => 90][$o] ?? 0;
|
||||
if ($rot) { $src = imagerotate($src, $rot, 0); $w = imagesx($src); $h = imagesy($src); }
|
||||
// Foto dal telefono: raddrizza secondo l'orientamento EXIF
|
||||
if ($mime === 'image/jpeg' && function_exists('exif_read_data')) {
|
||||
$o = (int) (@exif_read_data($f['tmp_name'])['Orientation'] ?? 1);
|
||||
$rot = [3 => 180, 6 => -90, 8 => 90][$o] ?? 0;
|
||||
if ($rot) {
|
||||
$src = imagerotate($src, $rot, 0);
|
||||
$w = imagesx($src);
|
||||
$h = imagesy($src);
|
||||
}
|
||||
}
|
||||
|
||||
$nw = min($w, 1200); // il doppio della larghezza email: nitida sugli schermi retina
|
||||
$nh = max(1, (int) round($h * $nw / $w));
|
||||
|
||||
// PNG con trasparenza resta PNG, il resto diventa JPG (molto più leggero)
|
||||
$keepPng = false;
|
||||
if ($mime === 'image/png') {
|
||||
$ct = ord((string) file_get_contents($f['tmp_name'], false, null, 25, 1));
|
||||
$keepPng = in_array($ct, [4, 6], true);
|
||||
}
|
||||
|
||||
$dst = imagecreatetruecolor($nw, $nh);
|
||||
if ($keepPng) {
|
||||
imagealphablending($dst, false);
|
||||
imagesavealpha($dst, true);
|
||||
} else {
|
||||
imagefill($dst, 0, 0, imagecolorallocate($dst, 255, 255, 255));
|
||||
}
|
||||
imagecopyresampled($dst, $src, 0, 0, 0, 0, $nw, $nh, $w, $h);
|
||||
|
||||
$file = $name . ($keepPng ? '.png' : '.jpg');
|
||||
$ok = $keepPng ? imagepng($dst, $dirAbs . '/' . $file, 9) : imagejpeg($dst, $dirAbs . '/' . $file, 82);
|
||||
imagedestroy($src);
|
||||
imagedestroy($dst);
|
||||
if (!$ok) fail('Impossibile salvare l\'immagine ottimizzata.', 500);
|
||||
[$w, $h] = [$nw, $nh];
|
||||
} catch (Throwable $e) {
|
||||
error_log('newsletter_api [upload_image]: ' . $e->getMessage());
|
||||
fail('Ottimizzazione non riuscita: ' . $e->getMessage(), 500);
|
||||
}
|
||||
|
||||
$maxW = 1200; // il doppio della larghezza email: nitida sugli schermi retina
|
||||
$nw = min($w, $maxW);
|
||||
$nh = (int) round($h * $nw / $w);
|
||||
|
||||
// PNG con trasparenza resta PNG, tutto il resto diventa JPG (molto più leggero)
|
||||
$keepPng = false;
|
||||
if ($mime === 'image/png') {
|
||||
$ct = ord(file_get_contents($f['tmp_name'], false, null, 25, 1));
|
||||
$keepPng = in_array($ct, [4, 6], true);
|
||||
}
|
||||
|
||||
$dst = imagecreatetruecolor($nw, $nh);
|
||||
if ($keepPng) {
|
||||
imagealphablending($dst, false);
|
||||
imagesavealpha($dst, true);
|
||||
} else {
|
||||
imagefill($dst, 0, 0, imagecolorallocate($dst, 255, 255, 255));
|
||||
}
|
||||
imagecopyresampled($dst, $src, 0, 0, 0, 0, $nw, $nh, $w, $h);
|
||||
|
||||
$file = $name . ($keepPng ? '.png' : '.jpg');
|
||||
$ok = $keepPng ? imagepng($dst, $dirAbs . '/' . $file, 9) : imagejpeg($dst, $dirAbs . '/' . $file, 82);
|
||||
imagedestroy($src);
|
||||
imagedestroy($dst);
|
||||
if (!$ok) fail('Impossibile salvare l\'immagine.', 500);
|
||||
[$w, $h] = [$nw, $nh];
|
||||
}
|
||||
|
||||
out([
|
||||
@@ -320,6 +354,7 @@ try {
|
||||
'width' => $w,
|
||||
'height' => $h,
|
||||
'kb' => (int) round(filesize($dirAbs . '/' . $file) / 1024),
|
||||
'note' => $note,
|
||||
]);
|
||||
|
||||
case 'send_test':
|
||||
@@ -413,8 +448,16 @@ try {
|
||||
$imp = NewsletterWp::import($wpId);
|
||||
// Se in WordPress non è ancora partita, la colleghiamo: "Pubblica" aggiornerà quella
|
||||
$status = NewsletterWp::statuses([$wpId])[$wpId] ?? '';
|
||||
$id = createDraft($pdo, $userId, $imp['subject'] ?: 'Importata da WordPress', $imp['subject'], $imp['preheader'],
|
||||
$imp['blocks'], $imp['settings'], $status === 'new' ? $wpId : null);
|
||||
$id = createDraft(
|
||||
$pdo,
|
||||
$userId,
|
||||
$imp['subject'] ?: 'Importata da WordPress',
|
||||
$imp['subject'],
|
||||
$imp['preheader'],
|
||||
$imp['blocks'],
|
||||
$imp['settings'],
|
||||
$status === 'new' ? $wpId : null
|
||||
);
|
||||
out(['success' => true, 'id' => $id, 'linked' => $status === 'new']);
|
||||
|
||||
default:
|
||||
|
||||
@@ -1219,7 +1219,8 @@ $jsonFlags = JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_
|
||||
$('#nlChecks').innerHTML = lastChecks.map(c =>
|
||||
'<div class="' + c[0] + '"><i class="fas ' + (c[0] === 'error' ? 'fa-circle-xmark' : 'fa-triangle-exclamation') + ' me-1"></i>' + esc(c[1]) + '</div>').join('');
|
||||
} catch (e) {
|
||||
/* l'anteprima riprova alla prossima modifica */ }
|
||||
/* l'anteprima riprova alla prossima modifica */
|
||||
}
|
||||
}
|
||||
|
||||
$$('.nl-device button').forEach(b => b.addEventListener('click', () => {
|
||||
@@ -1333,7 +1334,7 @@ $jsonFlags = JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_
|
||||
const t = $('[data-k="' + fileInput.dataset.upload + '"]', root);
|
||||
t.value = j.url;
|
||||
t.dispatchEvent(new Event('input'));
|
||||
info.textContent = 'Caricata: ' + j.width + '×' + j.height + ' px, ' + j.kb + ' KB';
|
||||
info.textContent = 'Caricata: ' + j.width + '×' + j.height + ' px, ' + j.kb + ' KB' + (j.note ? ' – ' + j.note : '');
|
||||
} catch (e) {
|
||||
info.textContent = '';
|
||||
Swal.fire('Immagine non caricata', e.message || 'Errore di rete.', 'error');
|
||||
|
||||
Reference in New Issue
Block a user