From 5f1dbd9e19308be29cb199088c9cdc50939faede Mon Sep 17 00:00:00 2001 From: Jacek Pyziak Date: Sun, 8 Feb 2026 22:07:22 +0100 Subject: [PATCH] =?UTF-8?q?Zaktualizuj=20funkcj=C4=99=20wysy=C5=82ania=20e?= =?UTF-8?q?-maili,=20aby=20obs=C5=82ugiwa=C5=82a=20wiele=20za=C5=82=C4=85c?= =?UTF-8?q?znik=C3=B3w=20oraz=20dodaj=20walidacj=C4=99=20plik=C3=B3w?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- konfigurator-mail.php | 94 ++++++- wp-content/themes/ostal_WP/page-2101.php | 339 ++++++++++++++++++++--- 2 files changed, 381 insertions(+), 52 deletions(-) diff --git a/konfigurator-mail.php b/konfigurator-mail.php index 779b361..da02168 100644 --- a/konfigurator-mail.php +++ b/konfigurator-mail.php @@ -3,7 +3,7 @@ session_start(); require_once 'phpmailer/class.phpmailer.php'; require_once 'phpmailer/class.smtp.php'; -function send_email( $email, $reply, $subject, $text, $attachment = null ) +function send_email( $email, $reply, $subject, $text, $attachments = array() ) { $mail = new PHPMailer; $mail -> IsSMTP(); @@ -27,17 +27,88 @@ function send_email( $email, $reply, $subject, $text, $attachment = null ) $mail -> isHTML( true ); $mail -> Subject = $subject; $mail -> Body = $text; - - if ($attachment && isset($attachment['tmp_name']) && file_exists($attachment['tmp_name'])) { - $mail->addAttachment($attachment['tmp_name'], $attachment['name']); + + // Obsługa wielu załączników + if (is_array($attachments) && count($attachments) > 0) { + foreach ($attachments as $attachment) { + if (isset($attachment['tmp_name']) && file_exists($attachment['tmp_name'])) { + $mail->addAttachment($attachment['tmp_name'], $attachment['name']); + } + } } return $mail -> send(); } + +function validate_file($file) { + $maxSize = 10 * 1024 * 1024; // 10MB + $allowedExtensions = array('jpg', 'jpeg', 'png', 'pdf', 'doc', 'docx', 'xls', 'xlsx'); + $allowedMimeTypes = array( + 'image/jpeg', + 'image/jpg', + 'image/png', + 'application/pdf', + 'application/msword', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'application/vnd.ms-excel', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' + ); + + // Sprawdź czy plik istnieje + if (!isset($file['tmp_name']) || !file_exists($file['tmp_name'])) { + return array('valid' => false, 'error' => 'Plik nie istnieje'); + } + + // Sprawdź rozmiar + if ($file['size'] > $maxSize) { + return array('valid' => false, 'error' => 'Plik jest za duży (max 10MB)'); + } + + // Sprawdź rozszerzenie + $fileExtension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)); + if (!in_array($fileExtension, $allowedExtensions)) { + return array('valid' => false, 'error' => 'Niedozwolone rozszerzenie pliku'); + } + + // Sprawdź MIME type + $finfo = finfo_open(FILEINFO_MIME_TYPE); + $mimeType = finfo_file($finfo, $file['tmp_name']); + finfo_close($finfo); + + if (!in_array($mimeType, $allowedMimeTypes)) { + return array('valid' => false, 'error' => 'Niedozwolony typ pliku'); + } + + return array('valid' => true); +} if ($_SERVER['REQUEST_METHOD'] === 'POST') { $configData = json_decode($_POST['configData'], true); - $file = isset($_FILES['attachment']) ? $_FILES['attachment'] : null; + // Pobierz wszystkie załączniki + $attachments = array(); + $attachments_count = isset($_POST['attachments_count']) ? intval($_POST['attachments_count']) : 0; + + // Walidacja liczby załączników (max 10) + if ($attachments_count > 10) { + echo json_encode(['status' => 'error', 'message' => 'Maksymalnie 10 załączników']); + exit(); + } + + for ($i = 0; $i < $attachments_count; $i++) { + $fileKey = 'attachment_' . $i; + if (isset($_FILES[$fileKey])) { + $file = $_FILES[$fileKey]; + + // Walidacja pliku + $validation = validate_file($file); + if (!$validation['valid']) { + echo json_encode(['status' => 'error', 'message' => 'Błąd walidacji pliku: ' . $validation['error']]); + exit(); + } + + $attachments[] = $file; + } + } $to = 'kontakt@ostal.pl'; $subject = 'ostal.pl - Konfigurator'; @@ -94,7 +165,18 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $message .= ''; } - if (send_email($to, $configData['step_4']['email'], $subject, $message, $file)) { + // Dodaj informację o załącznikach + if (count($attachments) > 0) { + $message .= '

Załączniki (' . count($attachments) . '):

'; + $message .= ''; + } + + if (send_email($to, $configData['step_4']['email'], $subject, $message, $attachments)) { $_SESSION["configurator_sended"] = true; echo json_encode(['status' => 'ok', 'message' => 'Wiadmość wysłana']); } else { diff --git a/wp-content/themes/ostal_WP/page-2101.php b/wp-content/themes/ostal_WP/page-2101.php index 19e3f52..12459f8 100644 --- a/wp-content/themes/ostal_WP/page-2101.php +++ b/wp-content/themes/ostal_WP/page-2101.php @@ -112,47 +112,6 @@

Orientacyjny budżet całorocznego ogrodu zimowego zwykle mieści się w przedziale 120 000 – 180 000 zł netto

- -
-

Przykłady cen ogrodu zimowego 4x5m

-
- - - -
-
- -
-
- Ogród zimowy Standard 4x5m -
-
-

Ogród zimowy Standard

-

Ogród zimowy standard z szybami Ug=1,1 na dachu i ścianach i z jednymi drzwiami tarasowymi uchylno-przesuwnymi PSK na frontowej ścianie 2,5x2,2m. Bez osłon przeciwsłonecznych (nadaje się w zacienione miejsca).

-
-
- -
-
- Ogród zimowy Comfort 4x5m -
-
-

Ogród zimowy Comfort

-

Ogród zimowy Comfort z szybami Ug=1,1 na dachu i ścianach i z dwoma drzwiami tarasowymi uchylno-przesuwnymi PSK na frontowej ścianie 2,5x2,2m + boczna ściana 3 kwatery 1 skrzydło PSK + osłona przeciwsłoneczna dachu, 2 osłony Veranda ster. elektr.

-
-
- -
-
- Ogród zimowy Premium 4x5m -
-
-

Ogród zimowy Premium

-

Ogród zimowy premium z szybami energooszczędnymi Ug=0,5 na dachu i ścianach i z dwoma drzwiami tarasowymi. 1 szt. uchylno-przesuwnymi PSK na frontowej ścianie 2,5x2,2m + 1 szt. drzwi HS na bocznej ścianie 1 skrzydło + komplet osłon przeciwsłonecznych na dachu, 2 osłony Veranda ster. elektr. z czujnikiem słońce wiatr + 1 szt. osłony przeciwsłoneczne żaluzje C80 na bocznych ścianach ster. el. + okno HS w dachu przesuwane, sterowane el. + oświetlenie punktowe LED z pilotem. Montaż na co drugiej krokwi.

-
-
-
-
@@ -227,6 +186,56 @@ + +
+

Przykłady cen ogrodu zimowego 4x5m

+
+ + + +
+
+ +
+
+ Ogród zimowy Standard 4x5m +
+
+

Ogród zimowy Classic 1 Standard.
Cena brutto 114.390,00 zł (z VAT 8%)

+

- Szyby izolacyjne Ug=1,1 na dachu i ścianach.
+- 1 szt. drzwi tarasowe uchylno-przesuwnymi PSK na frontowej ścianie.
+- Bez osłon przeciwsłonecznych. (w zacienione miejsca)

+
+
+ +
+
+ Ogród zimowy Comfort 4x5m +
+
+

Ogród zimowy Classic 2 Comfort.
Cena brutto 142.819,00 zł (z VAT 8%)

+

- Szyby izolacyjne Ug=1,1 na dachu i ścianach.
+- 2 szt. drzwi tarasowych uchylno-przesuwnymi PSK na ścianie frontowej i ścianie bocznej.
+- Komplet osłon przeciwsłonecznych na dachu. 2 osłony Veranda ster. Elektr + pilot.

+
+
+ +
+
+ Ogród zimowy Premium 4x5m +
+
+

Ogród zimowy Classic 3 Premium.
Cena brutto 203.550,00 zł (z VAT 8%)

+

- Szyby Energooszczędne Ug=0,5 na dachu i ścianach.
+- 1 szt. drzwi tarasowych uchylno-przesuwnymi PSK na frontowej ścianie + 1 szt. drzwi unoszono przesuwne HS na bocznej ścianie.
+- Komplet osłon przeciwsłonecznych na dachu. 2 osłony Veranda ster. Elektr. + pilot + czujnik słoneczno-wiatrowy.
+- Osłony przeciwsłoneczne ścian żaluzje C80 sterowane ele. + pilot.
+- Okno HS w dachu przesuwane, sterowane ele.
+- oświetlenie punktowe LED z pilotem.

+
+
+
+
@@ -292,7 +301,46 @@
  • {{acfData.acf.step_4.attachment}}

    - +
    + +
    + + + + + +

    Przeciągnij pliki tutaj lub kliknij aby wybrać

    +

    Dozwolone: JPG, PNG, PDF, DOC, DOCX, XLS, XLSX (max 10MB każdy)

    +
    +
    +
    +
    + + + + + {{ file.name }} + ({{ formatFileSize(file.size) }}) + +
    +
    +

    {{ fileError }}

  • @@ -451,6 +499,9 @@ showDatepicker: false, dpMonth: new Date().getMonth(), dpYear: new Date().getFullYear(), + uploadedFiles: [], + isDragOver: false, + fileError: '', acfData: { acf: {} @@ -557,10 +608,11 @@ formData.append('configData', JSON.stringify(this.configData)); - const file = this.$refs.fileInput?.files[0]; - if (file) { - formData.append('attachment', file); - } + // Dodaj wszystkie załączone pliki + this.uploadedFiles.forEach((file, index) => { + formData.append(`attachment_${index}`, file); + }); + formData.append('attachments_count', this.uploadedFiles.length); // const data = { // configData: this.configData, // }; @@ -641,6 +693,8 @@ this.selected_option_1 = null this.selected_option_3 = null + this.uploadedFiles = [] + this.fileError = '' while (stack.length > 0) { const obj = stack.pop(); @@ -696,6 +750,82 @@ const now = new Date(); return day === now.getDate() && this.dpMonth === now.getMonth() && this.dpYear === now.getFullYear(); }, + handleFileDrop(e) { + this.isDragOver = false; + const files = Array.from(e.dataTransfer.files); + this.addFiles(files); + }, + handleFileSelect(e) { + const files = Array.from(e.target.files); + this.addFiles(files); + }, + addFiles(files) { + this.fileError = ''; + + for (const file of files) { + const validation = this.validateFile(file); + if (!validation.valid) { + this.fileError = validation.error; + continue; + } + + // Sprawdź czy plik już nie został dodany + const exists = this.uploadedFiles.some(f => f.name === file.name && f.size === file.size); + if (!exists) { + this.uploadedFiles.push(file); + } + } + + // Wyczyść input aby móc dodać ten sam plik ponownie + if (this.$refs.fileInput) { + this.$refs.fileInput.value = ''; + } + }, + validateFile(file) { + const maxSize = 10 * 1024 * 1024; // 10MB + const allowedTypes = [ + 'image/jpeg', + 'image/jpg', + 'image/png', + 'application/pdf', + 'application/msword', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'application/vnd.ms-excel', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' + ]; + const allowedExtensions = ['.jpg', '.jpeg', '.png', '.pdf', '.doc', '.docx', '.xls', '.xlsx']; + + // Sprawdź rozszerzenie pliku + const fileName = file.name.toLowerCase(); + const hasValidExtension = allowedExtensions.some(ext => fileName.endsWith(ext)); + + if (!hasValidExtension && !allowedTypes.includes(file.type)) { + return { + valid: false, + error: `Nieprawidłowy typ pliku: ${file.name}. Dozwolone: JPG, PNG, PDF, DOC, DOCX, XLS, XLSX` + }; + } + + if (file.size > maxSize) { + return { + valid: false, + error: `Plik ${file.name} jest za duży. Maksymalny rozmiar: 10MB` + }; + } + + return { valid: true }; + }, + removeFile(index) { + this.uploadedFiles.splice(index, 1); + this.fileError = ''; + }, + formatFileSize(bytes) { + if (bytes === 0) return '0 B'; + const k = 1024; + const sizes = ['B', 'KB', 'MB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + ' ' + sizes[i]; + }, getWindowWidth() { this.windowWidth = window.innerWidth; }, @@ -742,4 +872,121 @@ app.mount('#app') + + \ No newline at end of file