email send afetr export routine

This commit is contained in:
2026-09-23 11:40:57 +02:00
parent bb2ebcc122
commit f31ba24008
32 changed files with 1526 additions and 344 deletions
+1 -1
View File
@@ -41,7 +41,7 @@
"laravel/socialite": "^5.16",
"laravel/tinker": "^2.7",
"laravel/ui": "^4.0",
"phpmailer/phpmailer": "^6.9",
"phpmailer/phpmailer": "^7.1",
"phpoffice/phpspreadsheet": "^4.1",
"proengsoft/laravel-jsvalidation": "^4.0.0",
"robmorgan/phinx": "^0.16.12",
Generated
+11 -10
View File
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "557df76fdde549210349be369d479f5d",
"content-hash": "e54cf3e0bbc04b94b563b01620ac3416",
"packages": [
{
"name": "akaunting/laravel-setting",
@@ -4166,16 +4166,16 @@
},
{
"name": "phpmailer/phpmailer",
"version": "v6.9.3",
"version": "v7.1.1",
"source": {
"type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "2f5c94fe7493efc213f643c23b1b1c249d40f47e"
"reference": "1bc1716a507a65e039d4ac9d9adebbbd0d346e15"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/2f5c94fe7493efc213f643c23b1b1c249d40f47e",
"reference": "2f5c94fe7493efc213f643c23b1b1c249d40f47e",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/1bc1716a507a65e039d4ac9d9adebbbd0d346e15",
"reference": "1bc1716a507a65e039d4ac9d9adebbbd0d346e15",
"shasum": ""
},
"require": {
@@ -4189,13 +4189,14 @@
"doctrine/annotations": "^1.2.6 || ^1.13.3",
"php-parallel-lint/php-console-highlighter": "^1.0.0",
"php-parallel-lint/php-parallel-lint": "^1.3.2",
"phpcompatibility/php-compatibility": "^9.3.5",
"roave/security-advisories": "dev-latest",
"squizlabs/php_codesniffer": "^3.7.2",
"phpcompatibility/php-compatibility": "^10.0.0@dev",
"squizlabs/php_codesniffer": "^3.13.5",
"yoast/phpunit-polyfills": "^1.0.4"
},
"suggest": {
"decomplexity/SendOauth2": "Adapter for using XOAUTH2 authentication",
"directorytree/imapengine": "For uploading sent messages via IMAP, see gmail example",
"ext-imap": "Needed to support advanced email address parsing according to RFC822",
"ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses",
"ext-openssl": "Needed for secure SMTP sending and DKIM signing",
"greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication",
@@ -4235,7 +4236,7 @@
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"support": {
"issues": "https://github.com/PHPMailer/PHPMailer/issues",
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.9.3"
"source": "https://github.com/PHPMailer/PHPMailer/tree/v7.1.1"
},
"funding": [
{
@@ -4243,7 +4244,7 @@
"type": "github"
}
],
"time": "2024-11-24T18:04:13+00:00"
"time": "2026-05-18T08:06:14+00:00"
},
{
"name": "phpoffice/phpspreadsheet",
@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
use Phinx\Migration\AbstractMigration;
final class AddNotifyExportEmailToAuthUsers extends AbstractMigration
{
public function change(): void
{
$table = $this->table('auth_users');
if (!$table->hasColumn('notify_export_email')) {
$table->addColumn('notify_export_email', 'boolean', [
'default' => true, // di default ricevono la mail
'null' => false,
'after' => 'lims_global_user_id',
])->update();
}
}
}
@@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
use Phinx\Migration\AbstractMigration;
final class AddAnalysisPriceToPartAnalyses extends AbstractMigration
{
public function change(): void
{
$this->table('identification_parts_analyses')
->addColumn('analysis_price', 'decimal', [
'precision' => 10,
'scale' => 2,
'null' => true,
'default' => null,
'after' => 'analysis_level',
])
->update();
}
}
+22 -1
View File
@@ -166,6 +166,7 @@
is_web_selectable: rowEl.getAttribute("data-web") === "1" ? 1 : 0,
is_accredited:
rowEl.getAttribute("data-accredited") === "1" ? 1 : 0,
analysis_price: rowEl.getAttribute("data-price") || "0",
};
}
@@ -196,6 +197,10 @@
: null,
is_web_selectable: payload.is_web_selectable,
is_accredited: payload.is_accredited,
analysis_price:
payload.analysis_price !== ""
? parseFloat(payload.analysis_price)
: null,
});
}
}
@@ -247,6 +252,7 @@
analysis_level: payload.analysis_level,
is_web_selectable: payload.is_web_selectable,
is_accredited: payload.is_accredited,
analysis_price: payload.analysis_price,
},
})
.done(function (resp) {
@@ -389,6 +395,17 @@
const selectable = item.SelezionabileSuWeb === true;
const accredited = item.Accreditato === true;
const level = item.Livello ?? "";
const rawPrice = item.Prezzo;
const priceNum =
rawPrice === null ||
rawPrice === undefined ||
rawPrice === ""
? 0
: parseFloat(String(rawPrice).replace(",", "."));
const price = isNaN(priceNum) ? 0 : priceNum;
const hasPrice = price > 0;
const searchText = (
analysisName +
" " +
@@ -414,6 +431,10 @@
"</span>";
}
if (!hasPrice) {
badges += '<span class="badge bg-danger">No price</span>';
}
return `
<div
class="list-group-item analysis-analysis-item"
@@ -423,6 +444,7 @@
data-analysis-level="${escapeHtml(level)}"
data-web="${selectable ? "1" : "0"}"
data-accredited="${accredited ? "1" : "0"}"
data-price="${escapeHtml(price)}"
data-search="${escapeHtml(searchText)}"
>
<div class="fw-semibold">${escapeHtml(analysisName)}</div>
@@ -440,7 +462,6 @@
filterAnalysisList();
syncSelectedAnalysisRows();
}
function filterAnalysisList() {
const modal = document.getElementById("analysisModal");
if (!modal) return;
+50
View File
@@ -0,0 +1,50 @@
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception as PHPMailerException;
require_once __DIR__ . '/../../../vendor/autoload.php'; // aggiusta il path se serve
class Mailer
{
public static function send(array $to, string $subject, string $htmlBody, ?string $altBody = null): array
{
$mail = new PHPMailer(true);
try {
$mail->isSMTP();
$mail->Host = env('MAIL_HOST');
$mail->SMTPAuth = true;
$mail->Username = env('MAIL_USERNAME');
$mail->Password = env('MAIL_PASSWORD');
$mail->Port = (int) env('MAIL_PORT', 465);
$enc = env('MAIL_ENCRYPTION', 'ssl');
$mail->SMTPSecure = ($enc === 'tls')
? PHPMailer::ENCRYPTION_STARTTLS
: PHPMailer::ENCRYPTION_SMTPS;
$mail->CharSet = 'UTF-8';
$mail->setFrom(env('MAIL_FROM_ADDRESS'), env('MAIL_FROM_NAME', 'SmartTRF'));
foreach ($to as $addr) {
$addr = trim((string)$addr);
if ($addr !== '' && filter_var($addr, FILTER_VALIDATE_EMAIL)) {
$mail->addAddress($addr);
}
}
if (!$mail->getToAddresses()) {
return ['ok' => false, 'error' => 'Nessun destinatario valido'];
}
$mail->isHTML(true);
$mail->Subject = $subject;
$mail->Body = $htmlBody;
$mail->AltBody = $altBody ?: strip_tags($htmlBody);
$mail->send();
return ['ok' => true, 'error' => null];
} catch (PHPMailerException $e) {
error_log('Mailer error: ' . $mail->ErrorInfo);
return ['ok' => false, 'error' => $mail->ErrorInfo];
}
}
}
+98 -2
View File
@@ -24,6 +24,24 @@
if (overlay) overlay.style.display = "none";
}
function escHtml(v) {
return String(v ?? "")
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}
// Badge "No price" con tooltip dei nomi analisi (vuoto se count = 0)
function noPriceBadgeHTML(count, names) {
const n = parseInt(count, 10) || 0;
if (n <= 0) return "";
const title = (names || []).join("\n");
return `<span class="badge bg-danger no-price-badge" title="${escHtml(title)}" style="margin-left:6px; font-size:0.85em; cursor:help; vertical-align:middle;"><i class="fas fa-exclamation-triangle"></i> No price (${n})</span>`;
}
window.noPriceBadgeHTML = noPriceBadgeHTML;
function getGridRow(iddatadb) {
return document.querySelector(`.grid-row[data-id="${iddatadb}"]`);
}
@@ -34,6 +52,29 @@
);
}
// Invia la mail di riepilogo per gli iddatadb processati (fire-and-forget).
// Una sola chiamata a fine export (singolo o batch).
function sendExportSummaryMail(iddatadbList) {
const ids = (iddatadbList || [])
.map((v) => parseInt(v, 10))
.filter(Boolean);
if (!ids.length) return;
const body = new URLSearchParams();
ids.forEach((id) => body.append("ids[]", id));
const tid = window.gridMeta && window.gridMeta.templateId;
if (tid) body.append("template_id", tid);
fetch("send_export_summary.php", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: body.toString(),
})
.then((r) => r.json())
.then((res) => console.log("Summary mail:", res))
.catch((err) => console.warn("Summary mail failed:", err));
}
// ── Validation ──────────────────────────────────────────────────────
async function validateRows(rowsToValidate) {
@@ -142,6 +183,9 @@
if (idx >= 0) {
window.gridData[idx].status = "l";
window.gridData[idx].commessaweb = data.commessaweb;
window.gridData[idx].noPriceCount = data.noPriceCount || 0;
window.gridData[idx].noPriceAnalyses =
data.noPriceAnalyses || [];
}
// Update visible DOM row
@@ -168,6 +212,11 @@
statusCell.appendChild(cwSpan);
}
cwSpan.textContent = data.commessaweb;
const npHtml = noPriceBadgeHTML(
data.noPriceCount,
data.noPriceAnalyses,
);
if (npHtml) cwSpan.insertAdjacentHTML("beforeend", npHtml);
}
const exportBtn = gridRow.querySelector(".export-lims-btn");
if (exportBtn) {
@@ -195,8 +244,17 @@
msg.innerHTML =
`${data.message.replace(/\n/g, "<br>")}` +
`<br>ID CommessaWeb: ${data.idcommessaweb}` +
`<br>Codice CommessaWeb: ${data.commessaweb}` +
(data.totalPhotos > 0 ? `<br>Foto: ${data.totalPhotos}` : "");
`<br>Codice CommessaWeb: ${escHtml(data.commessaweb)}` +
noPriceBadgeHTML(data.noPriceCount, data.noPriceAnalyses) +
(data.totalPhotos > 0 ? `<br>Foto: ${data.totalPhotos}` : "") +
(data.noPriceCount > 0
? `<div class="mt-2 small text-danger fw-semibold">Analisi senza prezzo:</div>` +
`<ul class="mb-0 small text-danger">` +
(data.noPriceAnalyses || [])
.map((n) => `<li>${escHtml(n)}</li>`)
.join("") +
`</ul>`
: "");
label.textContent = "Esportazione Completata";
} else {
msg.textContent = `Errore: ${data.message}`;
@@ -386,6 +444,8 @@
data.message || "Unknown error",
);
showExportResult(data);
// Mail di riepilogo per la singola commessa
sendExportSummaryMail([iddatadb]);
} catch (error) {
if (gridRow) {
setRowExporting(gridRow, false);
@@ -633,6 +693,8 @@
let processed = 0,
succeeded = 0,
failed = 0;
const exportedList = []; // { commessaweb, noPriceCount, noPriceAnalyses }
const processedIds = []; // iddatadb processati (ok o errore) per la mail
disableAllRowButtons();
@@ -666,11 +728,17 @@
const gridRow = row || getGridRow(iddatadb);
if (gridRow) setRowExporting(gridRow, true);
processedIds.push(iddatadb);
try {
const data = await sendExport(iddatadb, batchUuid);
processed++;
if (data.success) {
succeeded++;
exportedList.push({
commessaweb: data.commessaweb,
noPriceCount: data.noPriceCount || 0,
noPriceAnalyses: data.noPriceAnalyses || [],
});
} else {
failed++;
const errIdx = getRowIndexByIddatadb(iddatadb);
@@ -703,6 +771,9 @@
enableAllRowButtons();
if (bar) bar.style.display = "none";
// Mail di riepilogo unica per tutto il batch processato
sendExportSummaryMail(processedIds);
// Re-render to reflect status changes, then restore error indicators
const gr = window.gridRenderer;
if (gr) gr.renderVisibleRows();
@@ -730,6 +801,31 @@
msgEl.innerHTML = `Exported: <strong>${succeeded}</strong><br>Errors: <strong>${failed}</strong>`;
}
if (exportedList.length) {
const npCommesse = exportedList.filter(
(x) => x.noPriceCount > 0,
).length;
msgEl.innerHTML +=
`<hr class="my-2">` +
(npCommesse > 0
? `<div class="small text-danger fw-semibold mb-1"><i class="fas fa-exclamation-triangle"></i> ${npCommesse} commesse con analisi senza prezzo</div>`
: "") +
`<div class="small fw-semibold mb-1">Commesse esportate:</div>` +
`<ul class="mb-0 ps-3">` +
exportedList
.map(
(x) =>
`<li><span style="font-family:monospace;">${escHtml(x.commessaweb || "—")}</span>` +
noPriceBadgeHTML(
x.noPriceCount,
x.noPriceAnalyses,
) +
`</li>`,
)
.join("") +
`</ul>`;
}
const modalEl = document.getElementById("exportResponseModal");
new bootstrap.Modal(modalEl, { keyboard: false }).show();
modalEl.addEventListener("hidden.bs.modal", cleanupBackdrop, {
+14 -1
View File
@@ -585,7 +585,7 @@ try {
// 🔹 STEP 6.3: Add Analyses (AnalisiCampione) via Campione({id})/AddAnalisi bound action
$stmt = $pdo->prepare("
SELECT part_id, analysis_recordkey, analysis_name, analysis_method
SELECT part_id, analysis_recordkey, analysis_name, analysis_method, analysis_price
FROM identification_parts_analyses
WHERE iddatadb = :iddatadb
ORDER BY part_id, id
@@ -593,6 +593,17 @@ try {
$stmt->execute(['iddatadb' => $iddatadb]);
$analysesRows = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Analisi senza prezzo (NULL o 0), una sola volta per recordkey
$noPriceAnalyses = [];
foreach ($analysesRows as $a) {
$price = $a['analysis_price'];
if ($price === null || (float)$price <= 0) {
$rk = (string)($a['analysis_recordkey'] ?? '');
$noPriceAnalyses[$rk] = $a['analysis_name'] ?: 'Unnamed analysis';
}
}
$noPriceAnalyses = array_values($noPriceAnalyses);
$partIdToIndex = [];
foreach ($parts as $idx => $part) {
$partIdToIndex[(int)$part['part_id']] = $idx;
@@ -810,6 +821,8 @@ try {
"totalAnalyses" => $totalAnalyses,
"addedAnalyses" => $addedAnalyses,
"failedAnalyses" => $failedAnalyses,
"noPriceCount" => count($noPriceAnalyses),
"noPriceAnalyses" => $noPriceAnalyses,
"message" => "Export successful",
"logFiles" => [
"step5_create" => $logFileStep5,
+8 -1
View File
@@ -588,7 +588,14 @@
: "To LIMS";
let html = `<span class="status-badge status-${esc(st)}">${label}</span>`;
if (row.commessaweb) {
html += `<span class="commessaweb-code" style="display:block; font-size:0.75em; color:#555; margin-top:2px;">${esc(row.commessaweb)}</span>`;
const npBadge =
typeof window.noPriceBadgeHTML === "function"
? window.noPriceBadgeHTML(
row.noPriceCount,
row.noPriceAnalyses,
)
: "";
html += `<span class="commessaweb-code" style="display:block; font-size:0.75em; color:#555; margin-top:2px;">${esc(row.commessaweb)}${npBadge}</span>`;
}
div.innerHTML = html;
div.classList.remove("editable-cell");
+2
View File
@@ -108,6 +108,8 @@
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item d-flex align-items-center" href="user-profile.php"><i class="bx bx-user fs-5"></i><span>Profile</span></a>
</li>
<li><a class="dropdown-item d-flex align-items-center" href="notification_settings.php"><i class="bx bx-user fs-5"></i><span>Notifications</span></a>
</li>
<?php if ($user->hasRole('Admin') || $user->hasRole('SuperUser')): ?>
<li>
<a class="dropdown-item d-flex align-items-center" href="user-admin.php">
+127
View File
@@ -0,0 +1,127 @@
<?php
include('include/headscript.php');
$db = DBHandlerSelect::getInstance();
$pdo = $db->getConnection();
$userId = (int)($iduserlogin ?? 0);
// Carica le preferenze correnti dell'utente
$prefs = ['notify_export_email' => 1];
if ($userId > 0) {
$s = $pdo->prepare("SELECT notify_export_email FROM auth_users WHERE id = ? LIMIT 1");
$s->execute([$userId]);
$row = $s->fetch(PDO::FETCH_ASSOC);
if ($row) {
$prefs['notify_export_email'] = (int)($row['notify_export_email'] ?? 1);
}
}
// Flash message post-save (via querystring)
$saved = isset($_GET['saved']) && $_GET['saved'] === '1';
?>
<!doctype html>
<html lang="it">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
<?php include('cssinclude.php'); ?>
<title>SmartTRF - Notifiche</title>
<style>
.notif-row {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 16px;
padding: 16px 0;
border-bottom: 1px solid #eef0f2;
}
.notif-row:last-child {
border-bottom: none;
}
.notif-text {
max-width: 640px;
}
.notif-text h6 {
margin: 0 0 4px;
font-size: 15px;
}
.notif-text p {
margin: 0;
font-size: 13px;
color: #6c757d;
}
.form-switch .form-check-input {
width: 2.6em;
height: 1.4em;
cursor: pointer;
}
</style>
</head>
<body>
<div class="wrapper">
<?php include('include/navbar.php'); ?>
<?php include('include/topbar.php'); ?>
<div class="page-wrapper">
<div class="page-content">
<div class="card radius-10">
<div class="card-header">
<div>
<h6 class="mb-0">Preferenze notifiche</h6>
<small class="text-muted">Scegli quali email vuoi ricevere da SmartTRF.</small>
</div>
</div>
<div class="card-body">
<?php if ($saved): ?>
<div class="alert alert-success py-2" role="alert">
<i class="fas fa-check-circle me-1"></i> Preferenze salvate.
</div>
<?php endif; ?>
<form action="update_notification_prefs.php" method="POST">
<input type="hidden" name="iduserlogin" value="<?= htmlspecialchars((string)$userId, ENT_QUOTES, 'UTF-8') ?>">
<!-- Notifica: commesse esportate -->
<div class="notif-row">
<div class="notif-text">
<h6>Ricezione email commesse esportate</h6>
<p>Ricevi un riepilogo via email al termine di ogni esportazione verso il LIMS (singola o in blocco), con l'esito di ciascuna commessa.</p>
</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch"
id="notify_export_email" name="notify_export_email" value="1"
<?= $prefs['notify_export_email'] === 1 ? 'checked' : '' ?>>
</div>
</div>
<!-- Qui in futuro altre notifiche, stessa struttura .notif-row -->
<div class="mt-4">
<button type="submit" class="btn btn-primary">
<i class="fas fa-save me-1"></i> Salva preferenze
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="overlay toggle-icon"></div>
<?php include('include/footer.php'); ?>
</div>
<?php include('jsinclude.php'); ?>
</body>
</html>
+7 -2
View File
@@ -22,6 +22,8 @@ try {
$analysisLevel = isset($_POST['analysis_level']) && $_POST['analysis_level'] !== '' ? (int)$_POST['analysis_level'] : null;
$isWebSelectable = isset($_POST['is_web_selectable']) ? (int)$_POST['is_web_selectable'] : 0;
$isAccredited = isset($_POST['is_accredited']) ? (int)$_POST['is_accredited'] : 0;
$analysisPriceRaw = str_replace(',', '.', trim((string)($_POST['analysis_price'] ?? '')));
$analysisPrice = is_numeric($analysisPriceRaw) ? round((float)$analysisPriceRaw, 2) : null;
if ($partId <= 0 || $analysisRecordkey === '') {
http_response_code(400);
@@ -42,7 +44,8 @@ try {
analysis_method,
analysis_level,
is_web_selectable,
is_accredited
is_accredited,
analysis_price
) VALUES (
:part_id,
:iddatadb,
@@ -52,7 +55,8 @@ try {
:analysis_method,
:analysis_level,
:is_web_selectable,
:is_accredited
:is_accredited,
:analysis_price
)
");
@@ -66,6 +70,7 @@ try {
':analysis_level' => $analysisLevel,
':is_web_selectable' => $isWebSelectable,
':is_accredited' => $isAccredited,
':analysis_price' => $analysisPrice,
]);
echo json_encode([
+294
View File
@@ -0,0 +1,294 @@
<?php
include('include/headscript.php');
require_once __DIR__ . '/class/Mailer.class.php';
header('Content-Type: application/json');
/**
* Risolve [IdCliente => Nominativo] leggendo la stessa cache di search_clienti.php.
* Non chiama l'API: usa cache/clienti.json (già mantenuto aggiornato dalla ricerca clienti).
*/
function resolveClientNames(array $ids): array
{
$ids = array_values(array_filter(array_map('intval', $ids), fn($v) => $v > 0));
if (empty($ids)) return [];
$cacheFile = __DIR__ . '/cache/clienti.json';
if (!file_exists($cacheFile)) return [];
$data = json_decode((string)@file_get_contents($cacheFile), true);
$clients = $data['value'] ?? [];
if (empty($clients)) return [];
// indicizza per IdCliente
$byId = [];
foreach ($clients as $c) {
$cid = (int)($c['IdCliente'] ?? 0);
if ($cid > 0) {
$byId[$cid] = trim((string)($c['Nominativo'] ?? ''));
}
}
$out = [];
foreach ($ids as $id) {
if (isset($byId[$id]) && $byId[$id] !== '') {
$out[$id] = $byId[$id];
}
}
return $out;
}
$db = DBHandlerSelect::getInstance();
$pdo = $db->getConnection();
// input: solo POST (endpoint che invia email — niente attivazione via URL)
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo json_encode(['success' => false, 'message' => 'Metodo non consentito']);
exit;
}
$ids = $_POST['ids'] ?? [];
if (!is_array($ids)) $ids = explode(',', (string)$ids);
$ids = array_values(array_filter(array_map('intval', $ids), fn($v) => $v > 0));
$templateId = (int)($_POST['template_id'] ?? 0);
if (empty($ids)) {
echo json_encode(['success' => false, 'message' => 'Nessun id']);
exit;
}
// Fallback: se il template_id non arriva, ricavalo dalla prima commessa
if ($templateId <= 0) {
$tq = $pdo->prepare("SELECT templateid FROM datadb WHERE iddatadb = ? LIMIT 1");
$tq->execute([$ids[0]]);
$templateId = (int)$tq->fetchColumn();
}
// tutti i main field del template (possono essere fino a 2), in ordine
$mainMappingIds = [];
$templateName = '';
if ($templateId > 0) {
$s = $pdo->prepare("
SELECT id FROM template_mapping
WHERE template_id = ? AND main_field = '1' AND is_visible_import = 1
ORDER BY field_order ASC, id ASC
");
$s->execute([$templateId]);
$mainMappingIds = array_map('intval', $s->fetchAll(PDO::FETCH_COLUMN));
// nome del template per l'intestazione mail
$t = $pdo->prepare("SELECT name FROM excel_templates WHERE id = ? LIMIT 1");
$t->execute([$templateId]);
$templateName = (string)$t->fetchColumn();
}
// esiti delle commesse
$ph = implode(',', array_fill(0, count($ids), '?'));
$sql = "
SELECT d.iddatadb, d.commessaweb, d.status, d.user_id,
d.idclient, d.ClienteFatturazione,
CONCAT(u.first_name,' ',u.last_name) AS user_name,
u.email AS user_email, u.notify_export_email
FROM datadb d
LEFT JOIN auth_users u ON d.user_id = u.id
WHERE d.iddatadb IN ($ph)
";
$stmt = $pdo->prepare($sql);
$stmt->execute($ids);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (empty($rows)) {
echo json_encode(['success' => false, 'message' => 'Righe non trovate']);
exit;
}
// --- Risoluzione nomi cliente (idclient + ClienteFatturazione) ---
$clientIdsToResolve = [];
foreach ($rows as $r) {
if (!empty($r['idclient'])) $clientIdsToResolve[(int)$r['idclient']] = true;
if (!empty($r['ClienteFatturazione'])) $clientIdsToResolve[(int)$r['ClienteFatturazione']] = true;
}
$clientNames = resolveClientNames(array_keys($clientIdsToResolve)); // [id => nome]
// helper: id cliente → nome, con fallback all'id se non risolto
$clientLabel = function ($id) use ($clientNames) {
$id = (int)$id;
if ($id <= 0) return '—';
return htmlspecialchars($clientNames[$id] ?? (string)$id);
};
// valori dei main field per ogni iddatadb — concatena i main valorizzati
$mainValues = [];
if (!empty($mainMappingIds)) {
$mph = implode(',', array_fill(0, count($mainMappingIds), '?'));
$s = $pdo->prepare("
SELECT id AS iddatadb, mapping_id, field_value
FROM import_data_details
WHERE id IN ($ph) AND mapping_id IN ($mph)
");
$s->execute(array_merge($ids, $mainMappingIds));
// raggruppa per iddatadb, mantenendo l'ordine dei main
$byRow = []; // iddatadb => [mapping_id => value]
foreach ($s->fetchAll(PDO::FETCH_ASSOC) as $r) {
$byRow[(int)$r['iddatadb']][(int)$r['mapping_id']] = $r['field_value'];
}
foreach ($byRow as $idd => $vals) {
$parts = [];
foreach ($mainMappingIds as $mid) { // ordine dei main
$v = trim((string)($vals[$mid] ?? ''));
if ($v !== '') $parts[] = $v;
}
$mainValues[$idd] = implode(' — ', $parts); // es. "descrizione — style code"
}
}
// analisi senza prezzo (NULL o 0) per ogni iddatadb
$noPriceByRow = []; // iddatadb => [ [part_number, part_description, analysis_name], ... ]
$s = $pdo->prepare("
SELECT a.iddatadb, MAX(a.analysis_name) AS analysis_name
FROM identification_parts_analyses a
WHERE a.iddatadb IN ($ph)
AND (a.analysis_price IS NULL OR a.analysis_price <= 0)
GROUP BY a.iddatadb, a.analysis_recordkey
ORDER BY a.iddatadb, analysis_name
");
$s->execute($ids);
foreach ($s->fetchAll(PDO::FETCH_ASSOC) as $r) {
$noPriceByRow[(int)$r['iddatadb']][] = $r;
}
$noPriceTotal = array_sum(array_map('count', $noPriceByRow));
// destinatari: utente/i dell'export che hanno la notifica attiva + admin fisso
$recipients = [];
foreach ($rows as $r) {
if (!empty($r['user_email']) && (int)($r['notify_export_email'] ?? 1) === 1) {
$recipients[$r['user_email']] = true;
}
}
$adminEmail = env('EXPORT_SUMMARY_ADMIN', 'admin@cesoft.io'); // sempre, indipendente dalla preferenza
if ($adminEmail) $recipients[$adminEmail] = true;
$recipients = array_keys($recipients);
// Se dopo il filtro non resta nessuno, non inviare
if (empty($recipients)) {
echo json_encode(['success' => true, 'message' => 'Nessun destinatario (notifiche disattivate)', 'recipients' => []]);
exit;
}
// conteggi
$okCount = 0;
$errCount = 0;
foreach ($rows as $r) {
if ($r['status'] === 'l') $okCount++;
elseif ($r['status'] === 'x') $errCount++;
}
$hasError = $errCount > 0;
// --- tabella righe ---
$rowsHtml = '';
foreach ($rows as $r) {
$st = $r['status'];
if ($st === 'l') {
$label = 'Inviata';
$bg = '#e6f4ea';
$col = '#1e7e34';
} elseif ($st === 'x') {
$label = 'ERRORE';
$bg = '#fdecea';
$col = '#c0392b';
} else {
$label = htmlspecialchars((string)$st);
$bg = '#fff8e1';
$col = '#8a6d3b';
}
$commessa = htmlspecialchars($r['commessaweb'] ?: '—');
$main = htmlspecialchars($mainValues[(int)$r['iddatadb']] ?? '—');
$committente = $clientLabel($r['idclient'] ?? 0);
$fatturazione = $clientLabel($r['ClienteFatturazione'] ?? 0);
$rowsHtml .= "<tr>
<td style='padding:10px 10px;border-bottom:1px solid #eee;font-family:monospace;white-space:nowrap;vertical-align:top;'>{$commessa}</td>
<td style='padding:10px 10px;border-bottom:1px solid #eee;word-break:break-word;vertical-align:top;'>{$committente}</td>
<td style='padding:10px 10px;border-bottom:1px solid #eee;word-break:break-word;vertical-align:top;'>{$fatturazione}</td>
<td style='padding:10px 10px;border-bottom:1px solid #eee;word-break:break-word;vertical-align:top;'>{$main}</td>
<td style='padding:10px 10px;border-bottom:1px solid #eee;text-align:center;white-space:nowrap;vertical-align:top;'>
<span style='display:inline-block;padding:3px 10px;border-radius:12px;background:{$bg};color:{$col};font-weight:600;font-size:13px;'>{$label}</span>
</td>
</tr>";
// sotto-riga: solo le analisi No Price di questa commessa
$np = $noPriceByRow[(int)$r['iddatadb']] ?? [];
if (!empty($np)) {
$items = '';
foreach ($np as $n) {
$analysisName = htmlspecialchars((string)($n['analysis_name'] ?: 'Unnamed analysis'));
$items .= "<li style='margin:2px 0;'>{$analysisName}</li>";
}
$npCount = count($np);
$rowsHtml .= "<tr>
<td colspan='5' style='padding:8px 12px 12px 24px;border-bottom:1px solid #eee;background:#fff5f5;'>
<div style='margin-bottom:4px;font-size:12px;color:#c0392b;font-weight:600;'>
<span style='display:inline-block;padding:2px 8px;border-radius:10px;background:#c0392b;color:#fff;font-size:11px;'>No price</span>
&nbsp;Analisi senza prezzo ({$npCount})
</div>
<ul style='margin:0;padding-left:18px;font-size:13px;color:#555;'>{$items}</ul>
</td>
</tr>";
}
}
$headerColor = $hasError ? '#c0392b' : '#1e7e34';
$headerText = $hasError ? 'Export completato con errori' : 'Export completato con successo';
$total = count($rows);
$html = "
<div style='font-family:Arial,Helvetica,sans-serif;max-width:820px;margin:0 auto;border:1px solid #e0e0e0;border-radius:8px;overflow:hidden;'>
<div style='background:{$headerColor};color:#fff;padding:18px 24px;'>
<h2 style='margin:0;font-size:18px;'>{$headerText}</h2>
<p style='margin:6px 0 0;font-size:13px;opacity:.9;'>Riepilogo esportazione verso LIMS" .
($templateName !== '' ? " &middot; Template: <strong>" . htmlspecialchars($templateName) . "</strong>" : "") . "</p>
<p style='margin:6px 0 0;font-size:13px;opacity:.95;'>
Committente: <strong>" . $clientLabel($rows[0]['idclient'] ?? 0) . "</strong>
&nbsp;&middot;&nbsp;
FatturazioneAvanzata: <strong>" . $clientLabel($rows[0]['ClienteFatturazione'] ?? 0) . "</strong>
</p>
</div>
<div style='padding:20px 24px;'>
<p style='margin:0 0 14px;font-size:14px;color:#333;'>
Totale commesse: <strong>{$total}</strong> &nbsp;•&nbsp;
<span style='color:#1e7e34;'>Inviate: {$okCount}</span> &nbsp;•&nbsp;
<span style='color:#c0392b;'>Errori: {$errCount}</span>" .
($noPriceTotal > 0 ? " &nbsp;•&nbsp; <span style='color:#c0392b;'>Analisi No price: {$noPriceTotal}</span>" : "") . "
</p>
<table style='width:100%;border-collapse:collapse;font-size:14px;table-layout:fixed;'>
<thead>
<tr style='background:#f5f5f5;'>
<th style='padding:10px 10px;text-align:left;border-bottom:2px solid #ddd;width:14%;'>Commessa</th>
<th style='padding:10px 10px;text-align:left;border-bottom:2px solid #ddd;width:24%;'>Committente</th>
<th style='padding:10px 10px;text-align:left;border-bottom:2px solid #ddd;width:24%;'>Fatturazione</th>
<th style='padding:10px 10px;text-align:left;border-bottom:2px solid #ddd;width:24%;'>Riferimento</th>
<th style='padding:10px 10px;text-align:center;border-bottom:2px solid #ddd;width:14%;'>Status</th>
</tr>
</thead>
<tbody>{$rowsHtml}</tbody>
</table>
" . ($hasError ? "<p style='margin:18px 0 0;padding:12px;background:#fdecea;border-left:4px solid #c0392b;color:#c0392b;font-size:13px;border-radius:4px;'>⚠️ Alcune commesse non sono state inviate al LIMS. Controlla la sezione <strong>Errors</strong> nell'applicazione per i dettagli e per rilanciarle.</p>" : "") . "
</div>
<div style='background:#fafafa;padding:14px 24px;font-size:12px;color:#999;border-top:1px solid #eee;'>
Messaggio automatico da SmartTRF — non rispondere a questa email.
</div>
</div>";
$subjectPrefix = $hasError ? '⚠️ Errori Export LIMS' : '✅ Export LIMS OK';
$subject = "{$subjectPrefix} — {$total} commesse ({$okCount} ok, {$errCount} err)";
$res = Mailer::send($recipients, $subject, $html);
echo json_encode([
'success' => $res['ok'],
'message' => $res['ok'] ? 'Mail inviata' : ('Mail non inviata: ' . $res['error']),
'recipients' => $recipients,
'counts' => ['ok' => $okCount, 'err' => $errCount, 'total' => $total],
]);
@@ -0,0 +1,38 @@
<?php
include('include/headscript.php');
$db = DBHandlerSelect::getInstance();
$pdo = $db->getConnection();
$userId = (int)($iduserlogin ?? 0);
if ($userId <= 0) {
header("Location: login.php");
exit;
}
// Ogni preferenza: colonna DB => 1 se checkbox spuntata, 0 altrimenti
$prefsMap = [
'notify_export_email' => isset($_POST['notify_export_email']) ? 1 : 0,
// in futuro: 'notify_altra_cosa' => isset($_POST['notify_altra_cosa']) ? 1 : 0,
];
try {
$sets = [];
$params = [];
foreach ($prefsMap as $col => $val) {
$sets[] = "`{$col}` = :{$col}";
$params[$col] = $val;
}
$params['id'] = $userId;
$sql = "UPDATE auth_users SET " . implode(', ', $sets) . " WHERE id = :id";
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
header("Location: notification_settings.php?saved=1");
exit;
} catch (Exception $e) {
error_log("Notification prefs update error: " . $e->getMessage());
header("Location: notification_settings.php?saved=0");
exit;
}
+11 -10
View File
@@ -5806,17 +5806,17 @@
},
{
"name": "phpmailer/phpmailer",
"version": "v6.9.3",
"version_normalized": "6.9.3.0",
"version": "v7.1.1",
"version_normalized": "7.1.1.0",
"source": {
"type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "2f5c94fe7493efc213f643c23b1b1c249d40f47e"
"reference": "1bc1716a507a65e039d4ac9d9adebbbd0d346e15"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/2f5c94fe7493efc213f643c23b1b1c249d40f47e",
"reference": "2f5c94fe7493efc213f643c23b1b1c249d40f47e",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/1bc1716a507a65e039d4ac9d9adebbbd0d346e15",
"reference": "1bc1716a507a65e039d4ac9d9adebbbd0d346e15",
"shasum": ""
},
"require": {
@@ -5830,13 +5830,14 @@
"doctrine/annotations": "^1.2.6 || ^1.13.3",
"php-parallel-lint/php-console-highlighter": "^1.0.0",
"php-parallel-lint/php-parallel-lint": "^1.3.2",
"phpcompatibility/php-compatibility": "^9.3.5",
"roave/security-advisories": "dev-latest",
"squizlabs/php_codesniffer": "^3.7.2",
"phpcompatibility/php-compatibility": "^10.0.0@dev",
"squizlabs/php_codesniffer": "^3.13.5",
"yoast/phpunit-polyfills": "^1.0.4"
},
"suggest": {
"decomplexity/SendOauth2": "Adapter for using XOAUTH2 authentication",
"directorytree/imapengine": "For uploading sent messages via IMAP, see gmail example",
"ext-imap": "Needed to support advanced email address parsing according to RFC822",
"ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses",
"ext-openssl": "Needed for secure SMTP sending and DKIM signing",
"greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication",
@@ -5846,7 +5847,7 @@
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)",
"thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication"
},
"time": "2024-11-24T18:04:13+00:00",
"time": "2026-05-18T08:06:14+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@@ -5878,7 +5879,7 @@
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"support": {
"issues": "https://github.com/PHPMailer/PHPMailer/issues",
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.9.3"
"source": "https://github.com/PHPMailer/PHPMailer/tree/v7.1.1"
},
"funding": [
{
+5 -5
View File
@@ -3,7 +3,7 @@
'name' => 'loshmis/vanguard',
'pretty_version' => 'dev-main',
'version' => 'dev-main',
'reference' => 'b19963808e5545f0b99bf0eba214b0c85b2f4b7b',
'reference' => 'bb2ebcc1223dd084e59588774fecbca9875d9daf',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -742,7 +742,7 @@
'loshmis/vanguard' => array(
'pretty_version' => 'dev-main',
'version' => 'dev-main',
'reference' => 'b19963808e5545f0b99bf0eba214b0c85b2f4b7b',
'reference' => 'bb2ebcc1223dd084e59588774fecbca9875d9daf',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -941,9 +941,9 @@
'dev_requirement' => true,
),
'phpmailer/phpmailer' => array(
'pretty_version' => 'v6.9.3',
'version' => '6.9.3.0',
'reference' => '2f5c94fe7493efc213f643c23b1b1c249d40f47e',
'pretty_version' => 'v7.1.1',
'version' => '7.1.1.0',
'reference' => '1bc1716a507a65e039d4ac9d9adebbbd0d346e15',
'type' => 'library',
'install_path' => __DIR__ . '/../phpmailer/phpmailer',
'aliases' => array(),
-15
View File
@@ -1,15 +0,0 @@
root = true
[*]
charset = utf-8
indent_size = 4
indent_style = space
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.{yml,yaml}]
indent_size = 2
+13 -12
View File
@@ -6,9 +6,9 @@
[![Test status](https://github.com/PHPMailer/PHPMailer/workflows/Tests/badge.svg)](https://github.com/PHPMailer/PHPMailer/actions)
[![codecov.io](https://codecov.io/gh/PHPMailer/PHPMailer/branch/master/graph/badge.svg?token=iORZpwmYmM)](https://codecov.io/gh/PHPMailer/PHPMailer)
[![Latest Stable Version](https://poser.pugx.org/phpmailer/phpmailer/v/stable.svg)](https://packagist.org/packages/phpmailer/phpmailer)
[![Total Downloads](https://poser.pugx.org/phpmailer/phpmailer/downloads)](https://packagist.org/packages/phpmailer/phpmailer)
[![License](https://poser.pugx.org/phpmailer/phpmailer/license.svg)](https://packagist.org/packages/phpmailer/phpmailer)
[![Latest Stable Version](https://img.shields.io/packagist/v/phpmailer/phpmailer?label=stable)](https://packagist.org/packages/phpmailer/phpmailer)
[![Total Downloads](https://img.shields.io/packagist/dt/phpmailer/phpmailer)](https://packagist.org/packages/phpmailer/phpmailer)
[![License](https://img.shields.io/github/license/PHPMailer/PHPMailer)](https://packagist.org/packages/phpmailer/phpmailer)
[![API Docs](https://github.com/phpmailer/phpmailer/workflows/Docs/badge.svg)](https://phpmailer.github.io/PHPMailer/)
[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/PHPMailer/PHPMailer/badge)](https://api.securityscorecards.dev/projects/github.com/PHPMailer/PHPMailer)
@@ -20,25 +20,26 @@
- Multipart/alternative emails for mail clients that do not read HTML email
- Add attachments, including inline
- Support for UTF-8 content and 8bit, base64, binary, and quoted-printable encodings
- SMTP authentication with LOGIN, PLAIN, CRAM-MD5, and XOAUTH2 mechanisms over SMTPS and SMTP+STARTTLS transports
- Full UTF-8 support when using servers that support `SMTPUTF8`.
- Support for iCal events in multiparts and attachments
- SMTP authentication with `LOGIN`, `PLAIN`, `CRAM-MD5`, and `XOAUTH2` mechanisms over SMTPS and SMTP+STARTTLS transports
- Validates email addresses automatically
- Protects against header injection attacks
- Error messages in over 50 languages!
- DKIM and S/MIME signing support
- Compatible with PHP 5.5 and later, including PHP 8.2
- Compatible with PHP 5.5 and later, including PHP 8.5
- Namespaced to prevent name clashes
- Much more!
## Why you might need it
Many PHP developers need to send email from their code. The only PHP function that supports this directly is [`mail()`](https://www.php.net/manual/en/function.mail.php). However, it does not provide any assistance for making use of popular features such as encryption, authentication, HTML messages, and attachments.
Many PHP developers need to send email from their code. The only PHP function that supports this directly is [`mail()`](https://www.php.net/manual/en/function.mail.php). However, it does not provide any assistance for making use of popular features such as authentication, HTML messages, and attachments.
Formatting email correctly is surprisingly difficult. There are myriad overlapping (and conflicting) standards, requiring tight adherence to horribly complicated formatting and encoding rules – the vast majority of code that you'll find online that uses the `mail()` function directly is just plain wrong, if not unsafe!
The PHP `mail()` function usually sends via a local mail server, typically fronted by a `sendmail` binary on Linux, BSD, and macOS platforms, however, Windows usually doesn't include a local mail server; PHPMailer's integrated SMTP client allows email sending on all platforms without needing a local mail server. Be aware though, that the `mail()` function should be avoided when possible; it's both faster and [safer](https://exploitbox.io/paper/Pwning-PHP-Mail-Function-For-Fun-And-RCE.html) to use SMTP to localhost.
*Please* don't be tempted to do it yourself – if you don't use PHPMailer, there are many other excellent libraries that
you should look at before rolling your own. Try [SwiftMailer](https://swiftmailer.symfony.com/)
, [Laminas/Mail](https://docs.laminas.dev/laminas-mail/), [ZetaComponents](https://github.com/zetacomponents/Mail), etc.
you should look at before rolling your own. Try [Symfony Mailer](https://symfony.com/doc/current/mailer.html), [Laminas/Mail](https://docs.laminas.dev/laminas-mail/), [ZetaComponents](https://github.com/zetacomponents/Mail), etc.
## License
This software is distributed under the [LGPL 2.1](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html) license, along with the [GPL Cooperation Commitment](https://gplcc.github.io/gplcc/). Please read [LICENSE](https://github.com/PHPMailer/PHPMailer/blob/master/LICENSE) for information on the software availability and distribution.
@@ -47,7 +48,7 @@ This software is distributed under the [LGPL 2.1](https://www.gnu.org/licenses/o
PHPMailer is available on [Packagist](https://packagist.org/packages/phpmailer/phpmailer) (using semantic versioning), and installation via [Composer](https://getcomposer.org) is the recommended way to install PHPMailer. Just add this line to your `composer.json` file:
```json
"phpmailer/phpmailer": "^6.9.2"
"phpmailer/phpmailer": "^7.0.0"
```
or run
@@ -74,10 +75,10 @@ require 'path/to/PHPMailer/src/PHPMailer.php';
require 'path/to/PHPMailer/src/SMTP.php';
```
If you're not using the `SMTP` class explicitly (you're probably not), you don't need a `use` line for the SMTP class. Even if you're not using exceptions, you do still need to load the `Exception` class as it is used internally.
If you're not using the `SMTP` class explicitly (you're probably not), you don't need a `use` line for it. Even if you're not using exceptions, you do still need to load the `Exception` class as it is used internally.
## Legacy versions
PHPMailer 5.2 (which is compatible with PHP 5.0 — 7.0) is no longer supported, even for security updates. You will find the latest version of 5.2 in the [5.2-stable branch](https://github.com/PHPMailer/PHPMailer/tree/5.2-stable). If you're using PHP 5.5 or later (which you should be), switch to the 6.x releases.
PHPMailer 5.2 (which is compatible with PHP 5.0 — 7.0) is no longer supported, even for security updates. You will find the latest version of 5.2 in the [5.2-stable branch](https://github.com/PHPMailer/PHPMailer/tree/5.2-stable). If you're using PHP 5.5 or later (which you should be), upgrade to a later release.
### Upgrading from 5.2
The biggest changes are that source files are now in the `src/` folder, and PHPMailer now declares the namespace `PHPMailer\PHPMailer`. This has several important effects – [read the upgrade guide](https://github.com/PHPMailer/PHPMailer/tree/master/UPGRADING.md) for more details.
@@ -95,7 +96,7 @@ use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
//Load Composer's autoloader
//Load Composer's autoloader (created by composer, not included with PHPMailer)
require 'vendor/autoload.php';
//Create an instance; passing `true` enables exceptions
+1 -1
View File
@@ -1 +1 @@
6.9.3
7.1.1
+8 -4
View File
@@ -42,22 +42,25 @@
"doctrine/annotations": "^1.2.6 || ^1.13.3",
"php-parallel-lint/php-console-highlighter": "^1.0.0",
"php-parallel-lint/php-parallel-lint": "^1.3.2",
"phpcompatibility/php-compatibility": "^9.3.5",
"roave/security-advisories": "dev-latest",
"squizlabs/php_codesniffer": "^3.7.2",
"phpcompatibility/php-compatibility": "^10.0.0@dev",
"squizlabs/php_codesniffer": "^3.13.5",
"yoast/phpunit-polyfills": "^1.0.4"
},
"suggest": {
"decomplexity/SendOauth2": "Adapter for using XOAUTH2 authentication",
"ext-imap": "Needed to support advanced email address parsing according to RFC822",
"ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses",
"ext-openssl": "Needed for secure SMTP sending and DKIM signing",
"greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication",
"hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication",
"league/oauth2-google": "Needed for Google XOAUTH2 authentication",
"psr/log": "For optional PSR-3 debug logging",
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)",
"thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication",
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)"
"directorytree/imapengine": "For uploading sent messages via IMAP, see gmail example"
},
"minimum-stability": "dev",
"prefer-stable": true,
"autoload": {
"psr-4": {
"PHPMailer\\PHPMailer\\": "src/"
@@ -71,6 +74,7 @@
"license": "LGPL-2.1-only",
"scripts": {
"check": "./vendor/bin/phpcs",
"style": "./vendor/bin/phpcbf",
"test": "./vendor/bin/phpunit --no-coverage",
"coverage": "./vendor/bin/phpunit",
"lint": [
+1 -1
View File
@@ -178,5 +178,5 @@ if (!isset($_GET['code'])) {
);
//Use this to interact with an API on the users behalf
//Use this to get a new access token if the old one expires
echo 'Refresh Token: ', htmlspecialchars($token->getRefreshToken());
echo 'Refresh Token: ', htmlspecialchars($token->getRefreshToken(), ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401);
}
@@ -34,3 +34,6 @@ $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() fejlede.';
$PHPMAILER_LANG['smtp_detail'] = 'Detalje: ';
$PHPMAILER_LANG['smtp_error'] = 'SMTP server fejl: ';
$PHPMAILER_LANG['variable_set'] = 'Kunne ikke definere eller nulstille variablen: ';
$PHPMAILER_LANG['no_smtputf8'] = 'Serveren understøtter ikke SMTPUTF8 som påkrævet for at sende til Unicode adresser';
$PHPMAILER_LANG['imap_recommended'] = 'Brug af forenklet adresseparser anbefales ikke. Installer PHP IMAP udvidelsen for fuld RFC822 parsing.';
$PHPMAILER_LANG['deprecated_argument'] = 'Udfaset argument: ';
+29 -18
View File
@@ -3,24 +3,35 @@
/**
* Esperanto PHPMailer language file: refer to English translation for definitive list
* @package PHPMailer
* @author Robin van der Vliet <info@robinvandervliet.com>
*/
$PHPMAILER_LANG['authenticate'] = 'Eraro de servilo SMTP : aŭtentigo malsukcesis.';
$PHPMAILER_LANG['connect_host'] = 'Eraro de servilo SMTP : konektado al servilo malsukcesis.';
$PHPMAILER_LANG['data_not_accepted'] = 'Eraro de servilo SMTP : neĝustaj datumoj.';
$PHPMAILER_LANG['empty_message'] = 'Teksto de mesaĝo mankas.';
$PHPMAILER_LANG['authenticate'] = 'SMTP-eraro: Ne eblis aŭtentigi.';
$PHPMAILER_LANG['buggy_php'] = 'Via versio de PHP estas trafita de cimo, kiu povas kaŭzi difektitajn mesaĝojn. Por ripari tion, ŝanĝu al sendado per SMTP, malŝaltu la opcion mail.add_x_header en via php.ini, ŝanĝu al MacOS aŭ Linux, aŭ ĝisdatigu vian PHP al versio 7.0.17+ aŭ 7.1.3+.';
$PHPMAILER_LANG['connect_host'] = 'SMTP-eraro: Ne eblis konektiĝi al la SMTP-gastiganto.';
$PHPMAILER_LANG['data_not_accepted'] = 'SMTP-eraro: Datumoj ne akceptitaj.';
$PHPMAILER_LANG['empty_message'] = 'Mesaĝokorpo malplena';
$PHPMAILER_LANG['encoding'] = 'Nekonata kodoprezento: ';
$PHPMAILER_LANG['execute'] = 'Lanĉi rulumadon ne eblis: ';
$PHPMAILER_LANG['file_access'] = 'Aliro al dosiero ne sukcesis: ';
$PHPMAILER_LANG['file_open'] = 'Eraro de dosiero: malfermo neeblas: ';
$PHPMAILER_LANG['from_failed'] = 'Jena adreso de sendinto malsukcesis: ';
$PHPMAILER_LANG['instantiate'] = 'Genero de retmesaĝa funkcio neeblis.';
$PHPMAILER_LANG['invalid_address'] = 'Retadreso ne validas: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' mesaĝilo ne subtenata.';
$PHPMAILER_LANG['provide_address'] = 'Vi devas tajpi almenaŭ unu recevontan retadreson.';
$PHPMAILER_LANG['recipients_failed'] = 'Eraro de servilo SMTP : la jenaj poŝtrecivuloj kaŭzis eraron: ';
$PHPMAILER_LANG['signing'] = 'Eraro de subskribo: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP konektado malsukcesis.';
$PHPMAILER_LANG['smtp_error'] = 'Eraro de servilo SMTP : ';
$PHPMAILER_LANG['variable_set'] = 'Variablo ne pravalorizeblas aŭ ne repravalorizeblas: ';
$PHPMAILER_LANG['extension_missing'] = 'Mankas etendo: ';
$PHPMAILER_LANG['execute'] = 'Ne eblis plenumi: ';
$PHPMAILER_LANG['extension_missing'] = 'Kromprogramo mankas: ';
$PHPMAILER_LANG['file_access'] = 'Ne eblis aliri la dosieron: ';
$PHPMAILER_LANG['file_open'] = 'Dosiera eraro: Ne eblis malfermi la dosieron: ';
$PHPMAILER_LANG['from_failed'] = 'La sekva(j) sendinto(j) malsukcesis: ';
$PHPMAILER_LANG['instantiate'] = 'Ne eblis funkciigi la retpoŝtan funkcion.';
$PHPMAILER_LANG['invalid_address'] = 'Nevalida adreso: ';
$PHPMAILER_LANG['invalid_header'] = 'Nevalida kaplinia nomo aŭ valoro';
$PHPMAILER_LANG['invalid_hostentry'] = 'Nevalida enigo de gastiganto: ';
$PHPMAILER_LANG['invalid_host'] = 'Nevalida gastiganto: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' retpoŝtilo ne estas subtenata.';
$PHPMAILER_LANG['provide_address'] = 'Vi devas provizi almenaŭ unu retpoŝtadreson de ricevonto.';
$PHPMAILER_LANG['recipients_failed'] = 'SMTP-eraro: La sekva(j) ricevonto(j) malsukcesis: ';
$PHPMAILER_LANG['signing'] = 'Subskriba eraro: ';
$PHPMAILER_LANG['smtp_code'] = 'SMTP-kodo: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'Pliaj SMTP-informoj: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'La SMTP-konektiĝo malsukcesis.';
$PHPMAILER_LANG['smtp_detail'] = 'Informoj: ';
$PHPMAILER_LANG['smtp_error'] = 'Eraro de SMTP-servilo: ';
$PHPMAILER_LANG['variable_set'] = 'Ne eblas agordi aŭ reagordi la variablon: ';
$PHPMAILER_LANG['no_smtputf8'] = 'La servilo ne subtenas SMTPUTF8, kiu estas bezonata por sendi al Unicode-adresoj.';
$PHPMAILER_LANG['imap_recommended'] = 'Uzado de la simpligita adresanalizilo ne estas rekomendita. Instalu la IMAP-kromprogramon por PHP por plena RFC822-analizado.';
$PHPMAILER_LANG['deprecated_argument'] = 'Malrekomendita argumento: ';
+4 -2
View File
@@ -9,7 +9,7 @@
*/
$PHPMAILER_LANG['authenticate'] = 'Error SMTP: Imposible autentificar.';
$PHPMAILER_LANG['buggy_php'] = 'Tu versión de PHP está afectada por un bug que puede resultar en mensajes corruptos. Para arreglarlo, cambia a enviar usando SMTP, deshabilita la opción mail.add_x_header en tu php.ini, cambia a MacOS o Linux, o actualiza tu PHP a la versión 7.0.17+ o 7.1.3+.';
$PHPMAILER_LANG['buggy_php'] = 'Tu versión de PHP ha sido afectada por un bug que puede resultar en mensajes corruptos. Para arreglarlo, cambia a enviar usando SMTP, deshabilita la opción mail.add_x_header en tu php.ini, cambia a MacOS o Linux, o actualiza tu PHP a la versión 7.0.17+ o 7.1.3+.';
$PHPMAILER_LANG['connect_host'] = 'Error SMTP: Imposible conectar al servidor SMTP.';
$PHPMAILER_LANG['data_not_accepted'] = 'Error SMTP: Datos no aceptados.';
$PHPMAILER_LANG['empty_message'] = 'El cuerpo del mensaje está vacío.';
@@ -18,7 +18,7 @@ $PHPMAILER_LANG['execute'] = 'Imposible ejecutar: ';
$PHPMAILER_LANG['extension_missing'] = 'Extensión faltante: ';
$PHPMAILER_LANG['file_access'] = 'Imposible acceder al archivo: ';
$PHPMAILER_LANG['file_open'] = 'Error de Archivo: Imposible abrir el archivo: ';
$PHPMAILER_LANG['from_failed'] = 'La(s) siguiente(s) direcciones de remitente fallaron: ';
$PHPMAILER_LANG['from_failed'] = 'La siguiente dirección de remitente falló: ';
$PHPMAILER_LANG['instantiate'] = 'Imposible crear una instancia de la función Mail.';
$PHPMAILER_LANG['invalid_address'] = 'Imposible enviar: dirección de email inválido: ';
$PHPMAILER_LANG['invalid_header'] = 'Nombre o valor de encabezado no válido';
@@ -34,3 +34,5 @@ $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() falló.';
$PHPMAILER_LANG['smtp_detail'] = 'Detalle: ';
$PHPMAILER_LANG['smtp_error'] = 'Error del servidor SMTP: ';
$PHPMAILER_LANG['variable_set'] = 'No se pudo configurar la variable: ';
$PHPMAILER_LANG['imap_recommended'] = 'No se recomienda usar el analizador de direcciones simplificado. Instala la extensión IMAP de PHP para un análisis RFC822 más completo.';
$PHPMAILER_LANG['deprecated_argument'] = 'Argumento obsoleto: ';
+10 -6
View File
@@ -3,27 +3,28 @@
/**
* Norwegian Bokmål PHPMailer language file: refer to English translation for definitive list
* @package PHPMailer
* @author Wera AS <wordpress@wera.no>
*/
$PHPMAILER_LANG['authenticate'] = 'SMTP-feil: Kunne ikke autentiseres.';
$PHPMAILER_LANG['buggy_php'] = 'Din versjon av PHP er berørt av en feil som kan føre til ødelagte meldinger. For å løse problemet kan du bytte til SMTP, deaktivere alternativet mail.add_x_header i php.ini, bytte til MacOS eller Linux eller oppgradere PHP til versjon 7.0.17+ eller 7.1.3+.';
$PHPMAILER_LANG['authenticate'] = 'SMTP-feil: Kunne ikke autentisere.';
$PHPMAILER_LANG['buggy_php'] = 'Din versjon av PHP er påvirket av en feil som kan føre til ødelagte meldinger. For å løse problemet kan du bytte til sending via SMTP, deaktivere mail.add_x_header-alternativet i php.ini, bytte til MacOS eller Linux, eller oppgradere PHP til versjon 7.0.17+ eller 7.1.3+.';
$PHPMAILER_LANG['connect_host'] = 'SMTP-feil: Kunne ikke koble til SMTP-vert.';
$PHPMAILER_LANG['data_not_accepted'] = 'SMTP-feil: data ikke akseptert.';
$PHPMAILER_LANG['empty_message'] = 'Meldingstekst mangler';
$PHPMAILER_LANG['empty_message'] = 'Meldingsinnholdet er tomt';
$PHPMAILER_LANG['encoding'] = 'Ukjent koding: ';
$PHPMAILER_LANG['execute'] = 'Kunne ikke utføres: ';
$PHPMAILER_LANG['extension_missing'] = 'Utvidelse mangler: ';
$PHPMAILER_LANG['file_access'] = 'Kunne ikke få tilgang til filen: ';
$PHPMAILER_LANG['file_open'] = 'Feil i fil: Kunne ikke åpne filen: ';
$PHPMAILER_LANG['from_failed'] = 'Følgende Fra-adresse mislyktes: ';
$PHPMAILER_LANG['instantiate'] = 'Kunne ikke instansiere e-postfunksjonen.';
$PHPMAILER_LANG['from_failed'] = 'Følgende avsenderadresse mislyktes: ';
$PHPMAILER_LANG['instantiate'] = 'Kunne ikke starte e-postfunksjonen.';
$PHPMAILER_LANG['invalid_address'] = 'Ugyldig adresse: ';
$PHPMAILER_LANG['invalid_header'] = 'Ugyldig headernavn eller verdi';
$PHPMAILER_LANG['invalid_hostentry'] = 'Ugyldig vertsinngang: ';
$PHPMAILER_LANG['invalid_host'] = 'Ugyldig vert: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' sender er ikke støttet.';
$PHPMAILER_LANG['provide_address'] = 'Du må oppgi minst én mottaker-e-postadresse.';
$PHPMAILER_LANG['recipients_failed'] = 'SMTP Feil: Følgende mottakeradresse feilet: ';
$PHPMAILER_LANG['recipients_failed'] = 'SMTP-feil: Følgende mottakeradresser feilet: ';
$PHPMAILER_LANG['signing'] = 'Signeringsfeil: ';
$PHPMAILER_LANG['smtp_code'] = 'SMTP-kode: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'Ytterligere SMTP-info: ';
@@ -31,3 +32,6 @@
$PHPMAILER_LANG['smtp_detail'] = 'Detaljer: ';
$PHPMAILER_LANG['smtp_error'] = 'SMTP-serverfeil: ';
$PHPMAILER_LANG['variable_set'] = 'Kan ikke angi eller tilbakestille variabel: ';
$PHPMAILER_LANG['no_smtputf8'] = 'Serveren støtter ikke SMTPUTF8, som er nødvendig for å sende til Unicode-adresser.';
$PHPMAILER_LANG['imap_recommended'] = 'Det anbefales ikke å bruke forenklet adresseanalyse. Installer PHP IMAP-utvidelsen for full RFC822-analyse.';
$PHPMAILER_LANG['deprecated_argument'] = 'Avviklet argument: ';
+11 -7
View File
@@ -4,10 +4,11 @@
* Dutch PHPMailer language file: refer to PHPMailer.php for definitive list.
* @package PHPMailer
* @author Tuxion <team@tuxion.nl>
* @author Robin van der Vliet <info@robinvandervliet.com>
*/
$PHPMAILER_LANG['authenticate'] = 'SMTP-fout: authenticatie mislukt.';
$PHPMAILER_LANG['buggy_php'] = 'PHP versie gededecteerd die onderhavig is aan een bug die kan resulteren in gecorrumpeerde berichten. Om dit te voorkomen, gebruik SMTP voor het verzenden van berichten, zet de mail.add_x_header optie in uw php.ini file uit, gebruik MacOS of Linux, of pas de gebruikte PHP versie aan naar versie 7.0.17+ or 7.1.3+.';
$PHPMAILER_LANG['buggy_php'] = 'PHP-versie gedetecteerd die onderhevig is aan een bug die kan resulteren in gecorrumpeerde berichten. Om dit te voorkomen, gebruik SMTP voor het verzenden van berichten, zet de optie mail.add_x_header in uw php.ini uit, gebruik MacOS of Linux, of pas de gebruikte PHP-versie aan naar versie 7.0.17+ or 7.1.3+.';
$PHPMAILER_LANG['connect_host'] = 'SMTP-fout: kon niet verbinden met SMTP-host.';
$PHPMAILER_LANG['data_not_accepted'] = 'SMTP-fout: data niet geaccepteerd.';
$PHPMAILER_LANG['empty_message'] = 'Berichttekst is leeg';
@@ -16,19 +17,22 @@ $PHPMAILER_LANG['execute'] = 'Kon niet uitvoeren: ';
$PHPMAILER_LANG['extension_missing'] = 'Extensie afwezig: ';
$PHPMAILER_LANG['file_access'] = 'Kreeg geen toegang tot bestand: ';
$PHPMAILER_LANG['file_open'] = 'Bestandsfout: kon bestand niet openen: ';
$PHPMAILER_LANG['from_failed'] = 'Het volgende afzendersadres is mislukt: ';
$PHPMAILER_LANG['from_failed'] = 'Het volgende afzenderadres is mislukt: ';
$PHPMAILER_LANG['instantiate'] = 'Kon mailfunctie niet initialiseren.';
$PHPMAILER_LANG['invalid_address'] = 'Ongeldig adres: ';
$PHPMAILER_LANG['invalid_header'] = 'Ongeldige header naam of waarde';
$PHPMAILER_LANG['invalid_header'] = 'Ongeldige headernaam of -waarde';
$PHPMAILER_LANG['invalid_hostentry'] = 'Ongeldige hostentry: ';
$PHPMAILER_LANG['invalid_host'] = 'Ongeldige host: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' mailer wordt niet ondersteund.';
$PHPMAILER_LANG['provide_address'] = 'Er moet minstens één ontvanger worden opgegeven.';
$PHPMAILER_LANG['recipients_failed'] = 'SMTP-fout: de volgende ontvangers zijn mislukt: ';
$PHPMAILER_LANG['signing'] = 'Signeerfout: ';
$PHPMAILER_LANG['smtp_code'] = 'SMTP code: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'Aanvullende SMTP informatie: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Verbinding mislukt.';
$PHPMAILER_LANG['smtp_code'] = 'SMTP-code: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'Aanvullende SMTP-informatie: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP-verbinding mislukt.';
$PHPMAILER_LANG['smtp_detail'] = 'Detail: ';
$PHPMAILER_LANG['smtp_error'] = 'SMTP-serverfout: ';
$PHPMAILER_LANG['variable_set'] = 'Kan de volgende variabele niet instellen of resetten: ';
$PHPMAILER_LANG['variable_set'] = 'Kan de volgende variabele niet instellen of herstellen: ';
$PHPMAILER_LANG['no_smtputf8'] = 'De server ondersteunt geen SMTPUTF8 dat nodig is om naar Unicode-adressen te sturen.';
$PHPMAILER_LANG['imap_recommended'] = 'Het gebruik van de vereenvoudigde adresparser is niet aanbevolen. Installeer de IMAP-extensie voor PHP voor volledige RFC822-ondersteuning.';
$PHPMAILER_LANG['deprecated_argument'] = 'Verouderd argument: ';
+22 -22
View File
@@ -5,29 +5,29 @@
* @package PHPMailer
*/
$PHPMAILER_LANG['authenticate'] = 'Błąd SMTP: Nie można przeprowadzić uwierzytelnienia.';
$PHPMAILER_LANG['buggy_php'] = 'Twoja wersja PHP zawiera błąd, który może powodować uszkodzenie wiadomości. Aby go naprawić, przełącz się na wysyłanie za pomocą SMTP, wyłącz opcję mail.add_x_header w php.ini, przełącz się na MacOS lub Linux lub zaktualizuj PHP do wersji 7.0.17+ lub 7.1.3+.';
$PHPMAILER_LANG['connect_host'] = 'Błąd SMTP: Nie można połączyć się z wybranym hostem.';
$PHPMAILER_LANG['data_not_accepted'] = 'Błąd SMTP: Dane nie zostały przyjęte.';
$PHPMAILER_LANG['empty_message'] = 'Wiadomość jest pusta.';
$PHPMAILER_LANG['encoding'] = 'Błędny sposób kodowania znaków: ';
$PHPMAILER_LANG['execute'] = 'Nie można uruchomić: ';
$PHPMAILER_LANG['extension_missing'] = 'Brakujące rozszerzenie: ';
$PHPMAILER_LANG['authenticate'] = 'Błąd SMTP: nie udało się przeprowadzić uwierzytelnienia.';
$PHPMAILER_LANG['buggy_php'] = 'Używana wersja PHP zawiera błąd, który może powodować uszkodzenie wiadomości. Aby temu zapobiec, użyj wysyłki przez SMTP, wyłącz opcję mail.add_x_header w php.ini, przejdź na macOS lub Linux, lub zaktualizuj PHP do wersji 7.0.17+ albo 7.1.3+.';
$PHPMAILER_LANG['connect_host'] = 'Błąd SMTP: nie udało się połączyć z serwerem (hostem).';
$PHPMAILER_LANG['data_not_accepted'] = 'Błąd SMTP: dane wiadomości nie zostały przyjęte przez serwer.';
$PHPMAILER_LANG['empty_message'] = 'Nie można wysłać pustej wiadomości.';
$PHPMAILER_LANG['encoding'] = 'Nieobsługiwane kodowanie znaków: ';
$PHPMAILER_LANG['execute'] = 'Nie udało się uruchomić polecenia: ';
$PHPMAILER_LANG['extension_missing'] = 'Brak wymaganego rozszerzenia PHP: ';
$PHPMAILER_LANG['file_access'] = 'Brak dostępu do pliku: ';
$PHPMAILER_LANG['file_open'] = 'Nie można otworzyć pliku: ';
$PHPMAILER_LANG['from_failed'] = 'Następujący adres nadawcy jest nieprawidłowy lub nie istnieje: ';
$PHPMAILER_LANG['instantiate'] = 'Nie można wywołać funkcji mail(). Sprawdź konfigurację serwera.';
$PHPMAILER_LANG['invalid_address'] = 'Nie można wysłać wiadomości, ' . 'następujący adres odbiorcy jest nieprawidłowy lub nie istnieje: ';
$PHPMAILER_LANG['invalid_header'] = 'Nieprawidłowa nazwa lub wartość nagłówka';
$PHPMAILER_LANG['file_open'] = 'Nie udało się otworzyć pliku: ';
$PHPMAILER_LANG['from_failed'] = 'Nieprawidłowy adres nadawcy: ';
$PHPMAILER_LANG['instantiate'] = 'Nie można zainicjować funkcji mail(). Sprawdź konfigurację serwera.';
$PHPMAILER_LANG['invalid_address'] = 'Nie można wysłać wiadomości. Nieprawidłowy adres odbiorcy: ';
$PHPMAILER_LANG['invalid_header'] = 'Nieprawidłowa nazwa lub wartość nagłówka.';
$PHPMAILER_LANG['invalid_hostentry'] = 'Nieprawidłowy wpis hosta: ';
$PHPMAILER_LANG['invalid_host'] = 'Nieprawidłowy host: ';
$PHPMAILER_LANG['provide_address'] = 'Należy podać prawidłowy adres email odbiorcy.';
$PHPMAILER_LANG['invalid_host'] = 'Nieprawidłowa nazwa hosta: ';
$PHPMAILER_LANG['provide_address'] = 'Musisz podać co najmniej jeden prawidłowy adres e-mail odbiorcy.';
$PHPMAILER_LANG['mailer_not_supported'] = 'Wybrana metoda wysyłki wiadomości nie jest obsługiwana.';
$PHPMAILER_LANG['recipients_failed'] = 'Błąd SMTP: Następujący odbiorcy są nieprawidłowi lub nie istnieją: ';
$PHPMAILER_LANG['signing'] = 'Błąd podpisywania wiadomości: ';
$PHPMAILER_LANG['smtp_code'] = 'Kod SMTP: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'Dodatkowe informacje SMTP: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'Wywołanie funkcji SMTP Connect() zostało zakończone niepowodzeniem.';
$PHPMAILER_LANG['smtp_detail'] = 'Szczegóły: ';
$PHPMAILER_LANG['smtp_error'] = 'Błąd SMTP: ';
$PHPMAILER_LANG['recipients_failed'] = 'Błąd SMTP: nie udało się wysłać do następujących odbiorców: ';
$PHPMAILER_LANG['signing'] = 'Błąd podpisywania wiadomości cyfrowo: ';
$PHPMAILER_LANG['smtp_code'] = 'Kod odpowiedzi SMTP: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'Dodatkowe informacje serwera SMTP: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'Nie udało się nawiązać połączenia za pomocą SMTP Connect().';
$PHPMAILER_LANG['smtp_detail'] = 'Szczegóły błędu: ';
$PHPMAILER_LANG['smtp_error'] = 'Błąd serwera SMTP: ';
$PHPMAILER_LANG['variable_set'] = 'Nie można ustawić lub zmodyfikować zmiennej: ';
+24 -17
View File
@@ -3,25 +3,32 @@
/**
* Portuguese (European) PHPMailer language file: refer to English translation for definitive list
* @package PHPMailer
* @author Jonadabe <jonadabe@hotmail.com>
* @author João Vieira <mail@joaovieira.eu>
*/
$PHPMAILER_LANG['authenticate'] = 'Erro do SMTP: Não foi possível realizar a autenticação.';
$PHPMAILER_LANG['connect_host'] = 'Erro do SMTP: Não foi possível realizar ligação com o servidor SMTP.';
$PHPMAILER_LANG['data_not_accepted'] = 'Erro do SMTP: Os dados foram rejeitados.';
$PHPMAILER_LANG['empty_message'] = 'A mensagem no e-mail está vazia.';
$PHPMAILER_LANG['authenticate'] = 'Erro SMTP: Falha na autenticação.';
$PHPMAILER_LANG['buggy_php'] = 'A sua versão do PHP tem um bug que pode causar mensagens corrompidas. Para resolver, utilize o envio por SMTP, desative a opção mail.add_x_header no ficheiro php.ini, mude para MacOS ou Linux, ou atualize o PHP para a versão 7.0.17+ ou 7.1.3+.';
$PHPMAILER_LANG['connect_host'] = 'Erro SMTP: Não foi possível ligar ao servidor SMTP.';
$PHPMAILER_LANG['data_not_accepted'] = 'Erro SMTP: Dados não aceites.';
$PHPMAILER_LANG['empty_message'] = 'A mensagem de e-mail está vazia.';
$PHPMAILER_LANG['encoding'] = 'Codificação desconhecida: ';
$PHPMAILER_LANG['execute'] = 'Não foi possível executar: ';
$PHPMAILER_LANG['file_access'] = 'Não foi possível aceder o ficheiro: ';
$PHPMAILER_LANG['file_open'] = 'Abertura do ficheiro: Não foi possível abrir o ficheiro: ';
$PHPMAILER_LANG['from_failed'] = 'Ocorreram falhas nos endereços dos seguintes remententes: ';
$PHPMAILER_LANG['instantiate'] = 'Não foi possível iniciar uma instância da função mail.';
$PHPMAILER_LANG['invalid_address'] = 'Não foi enviado nenhum e-mail para o endereço de e-mail inválido: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' mailer não é suportado.';
$PHPMAILER_LANG['provide_address'] = 'Tem de fornecer pelo menos um endereço como destinatário do e-mail.';
$PHPMAILER_LANG['recipients_failed'] = 'Erro do SMTP: O endereço do seguinte destinatário falhou: ';
$PHPMAILER_LANG['signing'] = 'Erro ao assinar: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() falhou.';
$PHPMAILER_LANG['smtp_error'] = 'Erro de servidor SMTP: ';
$PHPMAILER_LANG['variable_set'] = 'Não foi possível definir ou redefinir a variável: ';
$PHPMAILER_LANG['extension_missing'] = 'Extensão em falta: ';
$PHPMAILER_LANG['file_access'] = 'Não foi possível aceder ao ficheiro: ';
$PHPMAILER_LANG['file_open'] = 'Erro ao abrir o ficheiro: ';
$PHPMAILER_LANG['from_failed'] = 'O envio falhou para o seguinte endereço do remetente: ';
$PHPMAILER_LANG['instantiate'] = 'Não foi possível instanciar a função mail.';
$PHPMAILER_LANG['invalid_address'] = 'Endereço de e-mail inválido: ';
$PHPMAILER_LANG['invalid_header'] = 'Nome ou valor do cabeçalho inválido.';
$PHPMAILER_LANG['invalid_hostentry'] = 'Entrada de host inválida: ';
$PHPMAILER_LANG['invalid_host'] = 'Host inválido: ';
$PHPMAILER_LANG['mailer_not_supported'] = 'O cliente de e-mail não é suportado.';
$PHPMAILER_LANG['provide_address'] = 'Deve fornecer pelo menos um endereço de destinatário.';
$PHPMAILER_LANG['recipients_failed'] = 'Erro SMTP: Falha no envio para os seguintes destinatários: ';
$PHPMAILER_LANG['signing'] = 'Erro ao assinar: ';
$PHPMAILER_LANG['smtp_code'] = 'Código SMTP: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'Informações adicionais SMTP: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'Falha na função SMTP connect().';
$PHPMAILER_LANG['smtp_detail'] = 'Detalhes: ';
$PHPMAILER_LANG['smtp_error'] = 'Erro do servidor SMTP: ';
$PHPMAILER_LANG['variable_set'] = 'Não foi possível definir ou redefinir a variável: ';
@@ -8,6 +8,7 @@
* @author Mehmet Benlioğlu
* @author @yasinaydin
* @author Ogün Karakuş
* @author Mustafa Deniz Buksur
*/
$PHPMAILER_LANG['authenticate'] = 'SMTP Hatası: Oturum açılamadı.';
@@ -36,3 +37,7 @@ $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP connect() fonksiyonu başarısı
$PHPMAILER_LANG['smtp_detail'] = 'SMTP SMTP Detayı: ';
$PHPMAILER_LANG['smtp_error'] = 'SMTP sunucu hatası: ';
$PHPMAILER_LANG['variable_set'] = 'Değişken ayarlanamadı ya da sıfırlanamadı: ';
$PHPMAILER_LANG['no_smtputf8'] = 'Unicode adreslere gönderim için gereken SMTPUTF8 desteği sunucu tarafından desteklenmiyor.';
$PHPMAILER_LANG['imap_recommended'] = 'Basitleştirilmiş adres ayrıştırıcısını kullanmanız önerilmez. ' .
'Tam RFC822 ayrıştırma için PHP IMAP eklentisini yükleyin.';
$PHPMAILER_LANG['deprecated_argument'] = 'Kullanımdan kaldırılmış argüman: ';
File diff suppressed because it is too large Load Diff
+20 -6
View File
@@ -45,8 +45,9 @@ class POP3
* The POP3 PHPMailer Version number.
*
* @var string
* @deprecated This constant will be removed in PHPMailer 8.0. Use `PHPMailer::VERSION` instead.
*/
const VERSION = '6.9.3';
const VERSION = '7.1.1';
/**
* Default POP3 port number.
@@ -211,9 +212,9 @@ class POP3
} else {
$this->tval = (int) $timeout;
}
$this->do_debug = $debug_level;
$this->username = $username;
$this->password = $password;
$this->do_debug = (int) $debug_level;
$this->username = self::stripControls($username);
$this->password = self::stripControls($password);
//Reset the error log
$this->errors = [];
//Connect
@@ -318,7 +319,8 @@ class POP3
if (empty($password)) {
$password = $this->password;
}
$username = self::stripControls($username);
$password = self::stripControls($password);
//Send the Username
$this->sendString("USER $username" . static::LE);
$pop3_response = $this->getResponse();
@@ -406,7 +408,7 @@ class POP3
/**
* Checks the POP3 server response.
* Looks for for +OK or -ERR.
* Looks for +OK or -ERR.
*
* @param string $string
*
@@ -466,4 +468,16 @@ class POP3
"errno: $errno errstr: $errstr; errfile: $errfile; errline: $errline"
);
}
/**
* Strip all control chars from a string.
*
* @param $string
*
* @return string
*/
protected static function stripControls($string)
{
return preg_replace('/[\x00-\x1F\x7F]/u', '', $string);
}
}
+118 -10
View File
@@ -34,8 +34,9 @@ class SMTP
* The PHPMailer SMTP version number.
*
* @var string
* @deprecated This constant will be removed in PHPMailer 8.0. Use `PHPMailer::VERSION` instead.
*/
const VERSION = '6.9.3';
const VERSION = '7.1.1';
/**
* SMTP line break constant.
@@ -159,6 +160,15 @@ class SMTP
*/
public $do_verp = false;
/**
* Whether to use SMTPUTF8.
*
* @see https://www.rfc-editor.org/rfc/rfc6531
*
* @var bool
*/
public $do_smtputf8 = false;
/**
* The timeout value for connection, in seconds.
* Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2.
@@ -196,6 +206,7 @@ class SMTP
'Haraka' => '/[\d]{3} Message Queued \((.*)\)/',
'ZoneMTA' => '/[\d]{3} Message queued as (.*)/',
'Mailjet' => '/[\d]{3} OK queued as (.*)/',
'Gsmtp' => '/[\d]{3} 2\.0\.0 OK (.*) - gsmtp/',
];
/**
@@ -484,7 +495,9 @@ class SMTP
//PHP 5.6.7 dropped inclusion of TLS 1.1 and 1.2 in STREAM_CRYPTO_METHOD_TLS_CLIENT
//so add them back in manually if we can
if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
// phpcs:ignore PHPCompatibility.Constants.NewConstants.stream_crypto_method_tlsv1_2_clientFound
$crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
// phpcs:ignore PHPCompatibility.Constants.NewConstants.stream_crypto_method_tlsv1_1_clientFound
$crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
}
@@ -623,12 +636,49 @@ class SMTP
if (null === $OAuth) {
return false;
}
try {
$oauth = $OAuth->getOauth64();
//Start authentication
} catch (\Exception $e) {
// We catch all exceptions and convert them to PHPMailer exceptions to be able to
// handle them correctly later
throw new Exception("SMTP authentication error", 0, $e);
}
/*
* An SMTP command line can have a maximum length of 512 bytes, including the command name,
* so the base64-encoded OAUTH token has a maximum length of:
* 512 - 13 (AUTH XOAUTH2) - 2 (CRLF) = 497 bytes
* If the token is longer than that, the command and the token must be sent separately as described in
* https://www.rfc-editor.org/rfc/rfc4954#section-4
*/
if ($oauth === '') {
//Sending an empty auth token is legitimate, but it must be encoded as '='
//to indicate it's not a 2-part command
if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 =', 235)) {
return false;
}
} elseif (strlen($oauth) <= 497) {
//Authenticate using a token in the initial-response part
if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 ' . $oauth, 235)) {
return false;
}
} else {
//The token is too long, so we need to send it in two parts.
//Send the auth command without a token and expect a 334
if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2', 334)) {
return false;
}
//Send the token
if (!$this->sendCommand('OAuth TOKEN', $oauth, [235, 334])) {
return false;
}
//If the server answers with 334, send an empty line and wait for a 235
if (
substr($this->last_reply, 0, 3) === '334'
&& $this->sendCommand('AUTH End', '', 235)
) {
return false;
}
}
break;
default:
$this->setError("Authentication method \"$authtype\" is not supported");
@@ -720,6 +770,25 @@ class SMTP
}
}
private function iterateLines($s)
{
$start = 0;
$length = strlen($s);
for ($i = 0; $i < $length; $i++) {
$c = $s[$i];
if ($c === "\n" || $c === "\r") {
yield substr($s, $start, $i - $start);
if ($c === "\r" && $i + 1 < $length && $s[$i + 1] === "\n") {
$i++;
}
$start = $i + 1;
}
}
yield substr($s, $start);
}
/**
* Send an SMTP DATA command.
* Issues a data command and sends the msg_data to the server,
@@ -748,15 +817,16 @@ class SMTP
* NOTE: this does not count towards line-length limit.
*/
//Normalize line breaks before exploding
$lines = explode("\n", str_replace(["\r\n", "\r"], "\n", $msg_data));
//Iterate over lines with normalized line breaks
$lines = $this->iterateLines($msg_data);
/* To distinguish between a complete RFC822 message and a plain message body, we check if the first field
* of the first line (':' separated) does not contain a space then it _should_ be a header, and we will
* process all lines before a blank line as headers.
*/
$field = substr($lines[0], 0, strpos($lines[0], ':'));
$first_line = $lines->current();
$field = substr($first_line, 0, strpos($first_line, ':'));
$in_headers = false;
if (!empty($field) && strpos($field, ' ') === false) {
$in_headers = true;
@@ -913,7 +983,15 @@ class SMTP
* $from. Returns true if successful or false otherwise. If True
* the mail transaction is started and then one or more recipient
* commands may be called followed by a data command.
* Implements RFC 821: MAIL <SP> FROM:<reverse-path> <CRLF>.
* Implements RFC 821: MAIL <SP> FROM:<reverse-path> <CRLF> and
* two extensions, namely XVERP and SMTPUTF8.
*
* The server's EHLO response is not checked. If use of either
* extensions is enabled even though the server does not support
* that, mail submission will fail.
*
* XVERP is documented at https://www.postfix.org/VERP_README.html
* and SMTPUTF8 is specified in RFC 6531.
*
* @param string $from Source address of this message
*
@@ -922,10 +1000,11 @@ class SMTP
public function mail($from)
{
$useVerp = ($this->do_verp ? ' XVERP' : '');
$useSmtputf8 = ($this->do_smtputf8 ? ' SMTPUTF8' : '');
return $this->sendCommand(
'MAIL FROM',
'MAIL FROM:<' . $from . '>' . $useVerp,
'MAIL FROM:<' . $from . '>' . $useSmtputf8 . $useVerp,
250
);
}
@@ -1210,7 +1289,7 @@ class SMTP
* 3. EHLO has been sent -
* $name == 'HELO'|'EHLO': returns the server name
* $name == any other string: if extension $name exists, returns True
* or its options (e.g. AUTH mechanisms supported). Otherwise returns False.
* or its options (e.g. AUTH mechanisms supported). Otherwise, returns False.
*
* @param string $name Name of SMTP extension or 'HELO'|'EHLO'
*
@@ -1291,7 +1370,16 @@ class SMTP
//stream_select returns false when the `select` system call is interrupted
//by an incoming signal, try the select again
if (stripos($message, 'interrupted system call') !== false) {
if (
stripos($message, 'interrupted system call') !== false ||
(
// on applications with a different locale than english, the message above is not found because
// it's translated. So we also check for the SOCKET_EINTR constant which is defined under
// Windows and UNIX-like platforms (if available on the platform).
defined('SOCKET_EINTR') &&
stripos($message, 'stream_select(): Unable to select [' . SOCKET_EINTR . ']') !== false
)
) {
$this->edebug(
'SMTP -> get_lines(): retrying stream_select',
self::DEBUG_LOWLEVEL
@@ -1364,6 +1452,26 @@ class SMTP
return $this->do_verp;
}
/**
* Enable or disable use of SMTPUTF8.
*
* @param bool $enabled
*/
public function setSMTPUTF8($enabled = false)
{
$this->do_smtputf8 = $enabled;
}
/**
* Get SMTPUTF8 use.
*
* @return bool
*/
public function getSMTPUTF8()
{
return $this->do_smtputf8;
}
/**
* Set error messages and codes.
*