Formularz do wysyłki maili z załącznikiem - problem

Odpowiedz Nowy wątek
Polak
2018-06-02 18:17
Polak
0

Witam wszystkich. Mam problem z poniższym skryptem mojego autorstwa. Skrypt z założenia ma wykonywać:

  1. Po kliknięciu wyślij ma być wysłany do mnie mail.
  2. Schemat tematu wiadomości np. Problem/$counter/$date gdzie $counter to będzie zmienna zwiększana po każdym wysłaniu maila.
  3. Dodawanie załącznika/pliku graficznego do formularza i wysyłanie go.
  4. Walidacja żeby użytkownicy głupot nie wpisywali.
  5. Zapisywanie do bazy danych wysłanych mailem informacji. //tego jeszcze nie ma, będzie jak się uporam z tym co jest
  6. Rozmiar załączanego pliku ma być nie większy niż 2MB.

Na obecną chwilę po kliknięciu "Wyślij" żaden mail się nie wysyła. Od razu zaznaczę, że $headers ustawione na bazie przykładów znalezionych w sieci, więc mogą tam być błędy. Niestety $headers są wymagane do wysyłki maila z załącznikiem.

Bardzo proszę o wskazówki/pomoc.

<!DOCTYPE html>
<html>
    <head>
        <title>HelpDesk - wyślij problem</title>
        <style>
            .error {
                color: #FF0000;
            }
            .mailmsg {
                color: #00ddff;
            }
        </style>
    </head>
<body>

<?php

    //serwer
    //$server = "localhost";
    //admin
    //$admin = "root";
    //hasło
    //$pass = "ZAQ!2wsx";
    //nazwa bazy
    //$base = "test";
    //$dbconnection = mysqli_connect($server, $admin, $pass, $base) or die ("Brak połączenia z serwerem");

    $nameErr = $surnameErr = $companyErr = $emailErr = $commentErr = $upload_fileErr = "";
    $name = $surname = $company = $email = $comment = $upload_file = $mailMsg = $headers = $body = $content = "";
    $counter = 0;

    if ($_SERVER["REQUEST_METHOD"] == "POST"){
        /* można by było sprawdzać w jednym ifie czy pola są ustawione i jeśli nie
         * to zwracać jedno info, że nie są ustawione i wtedy dodać walidację w js
         * i by było lepiej bo nie po stronie serwera, czyli bez odświeżania strony
         */
        if (empty($_POST["name"])) {
            $nameErr = "Należy podać imię.";
        } else {
            $name = prepare_data($_POST["name"]);
            #sprawdzanie czy imię zawiera tylko litery i ma od 3 - 20 znaków
            if (!preg_match("/^[A-Z]([a-z]{3,20})$/", $name)){
                $nameErr = "Należy wpisywać litery. Imię o długości 3 - 20 znaków.";
            }
        }

        if (empty($_POST["surname"])) {
            $surnameErr = "Należy podać nazwisko.";
        } else {
            $surname = prepare_data($_POST["surname"]);
            if (!preg_match("/^[A-Z]([a-z]{3,20})$/", $surname)){
                $surnameErr = "Należy wpisywać litery. Nazwisko o długości 3 - 20 znaków.";
            }
        }

        if (empty($_POST["company"])) {
            $companyErr = "Należy podać nazwę firmy.";
        } else {
            $company = prepare_data($_POST["company"]);
            if (!preg_match("/^[A-Z]([a-z])$/", $company)){
                $companyErr = "Należy wpisywać litery.";
            }
        }

        if (empty($_POST["email"])) {
            $emailErr = "Należy podać email kontaktowy.";
        } else {
            $email = prepare_data($_POST["email"]);
            if (!filter_var($email, FILTER_VALIDATE_EMAIL)){
                $emailErr = "Należy podać poprawny email. Będzie użyty do kontaktu zwrotnego.";
            }
        }

        if (empty($_POST["comment"])) {
            $commentErr = "Należy opisać problem.";
        } else {
            $comment = prepare_data($_POST["comment"]);
        }

        #$upload_file = $_POST["upload_file"];
        $file = ($_FILES["upload_file"]["name"]);
        $fileType = strtolower(pathinfo($file, PATHINFO_EXTENSION));

        #plik został wysłany i do tego bez błędów
        if ($file && (!$_FILES["upload_file"]["error"])){
            #pozwalamy na konkretne formaty
            if ($fileType != "jpg" && $fileType != "png" && $fileType != "jpeg"){
                $upload_fileErr = "Dozwolone są tylko obrazki w formatach JPG, PNG, JPEG.";
            }

            #plik nie może być większy niż 2MB
            if ($file > (2048000)) {
                $upload_fileErr = "Plik jest większy niż 2MB.";
            }
            $content = chunk_split(base64_encode(file_get_contents($file)));
        } //else {
            //$upload_fileErr = "Wystąpił problem z dołączeniem pliku: kod ".$_FILES["upload_file"]["error"];
        //}

        $counter += 1;
        $toEmail = "[email protected]"; #mail gdzie ma lecieć wiadomość
        $subject = "Problem/$counter/date('Y/m/d h:i:sa')"; #format tematu -> Problem/kolejny_numer_inkrementowany_po_każdym_wysłaniu_formularza/data Y/M/D H:M:S

        #oddziela kolejne części maila
        $strSid = md5(uniqid(time()));

        $eol = "\r\n";

        #main header
        $headers .= "From: $email" . $eol;
        $headers .= "MIME-version: 1.0" . $eol;
        $headers .= "Content-Type: multipart/mixed; boundary=\"" . $strSid . "\"" . $eol;
        $headers .= "Content-Transfer-Encoding: 7bit" . $eol;
        $headers .= "This is a MIME encoded message." . $eol;

        #treść
        $body .= "--" . $strSid . $eol;
        $body .= "Content-Type: text/plain; charset=utf-8" . $eol;
        $body .= "Content-Transfer-Encoding: 8bit" . $eol;
        $body .= $comment . $eol;

        #załącznik
        $body .= "--" . $strSid . $eol;
        $body .= "Content-Type: application/octet-stream; name=\"" . $file . "\"" . $eol;
        $body .= "Content-Transfer-Encoding: base64" . $eol;
        $body .= "Content-Disposition: attachement" .$eol;
        $body .= $content . $eol;
        $body .= "--" . $strSid . "--";

        #wysyłka maila
        if (mail($toEmail, $subject, $body, $headers)) {#za $comment moze być np. $body .= $comment
            $mailMsg = "Mail został wysłany.";
            echo '<span class="mailmsg"><?php echo $mailMsg; ?></span>"';
        } else {
            $mailMsg = "Nie udało się wysłać maila.";
            echo '<span class="mailmsg"><?php echo $mailMsg; ?></span>"';
        }

    }   

    #usuwanie niepotrzebnych znaków w razie jakby miały się pojawić
    function prepare_data($form_data) {
        $form_data = trim($form_data); #skasowanie białych znaków
        $form_data = stripslashes($form_data); #kasowanie backslashy
        #return $form_data; #ciekawe czy zwróci automatycznie dane czy trzeba je ręcznie zwracać
    }
?>
    <p><span class="error">* wymagane pola</span></p>

    <form action="helpdesk.php" method="post" enctype="multipart/form-data">
        <label for="name">Imię:</label>
        <input type="text" name="name"><span class="error">* <?php echo $nameErr; ?></span><br>
        <label for="surname">Nazwisko:</label> 
        <input type="text" name="surname"><span class="error">* <?php echo $surnameErr; ?></span><br>
        <label for="company">Firma:</label> 
        <input type="text" name="company"><span class="error">* <?php echo $companyErr; ?></span><br>
        <label for="email">Email:</label> 
        <input type="text" name="email"><span class="error">* <?php echo $emailErr; ?></span><br>
        <label for="comment">Problem:</label> 
        <textarea name="comment" rows="5" cols="40"></textarea><span class="error">* <?php echo $commentErr; ?></span><br>
        <label for="upload_file">Wybierz plik do podesłania:</label><br> 
        <input type="file" name="upload_file"><span class="error"><?php echo $upload_fileErr; ?></span>
        <input type="submit" name="submit" value="Wyślij">
    </form>

</body>
</html> 

Pozostało 580 znaków

2018-06-02 19:59

Rejestracja: 2 lata temu

Ostatnio: 1 dzień temu

0

A działa Ci sendmail albo serwer smtp? Bez tego nie da się wysłać maili.

Pozostało 580 znaków

Polak
2018-06-02 21:36
Polak
0
pesymistycznyoptymista napisał(a):

A działa Ci sendmail albo serwer smtp? Bez tego nie da się wysłać maili.

Używałem xampp do odpalenia skryptu i włączałem tylko serwer apache. Przyznam szczerze, że nie wiedziałem, że cokolwiek muszę ekstra włączać (przyzwyczajenia z pisania w bash na linux) no i nie widziałem w xampp sendmail.

https://stackoverflow.com/que[...]p;utm_campaign=google_rich_qa lub kup jakiś hosting taniutki do testowanie. Na home.pl chyba 15zł. - Ferdyrurka 2018-06-02 22:04

Pozostało 580 znaków

Polak
2018-06-02 22:16
Polak
0

Rzeczywiście. Pogoglowałem chwilę, skonfigurowałem i wysyłanie maila działa, ale są błędy. Wiadomość, która dociera zawiera załącznik, który waży 0kb i nie mam treści w wiadomości. Natomiast w przeglądarce pojawia się Warning: file_get_contents(TRS 301 with full upgrades.jpg): failed to open stream: No such file or directory in D:\programy\xampp\htdocs\skrypt.php on line 108. Fakt, nie ma tego pliku w tej ścieżce, ale klikając na "Przeglądaj..." wskazałem ten plik, bo on fizycznie istnieje, tyle że nie w tej lokalizacji z powyższego warninga.
Poza tym nie rozumiem dlaczego po wciśnięciu "Wyślij" wszystkie pola są walidowane tak jakby w ogóle nic w nie nie było wpisane. Żaden komunikat przy którymkolwiek inpucie nie powinien się pojawić po wciśnięciu "Wyślij".

Pozostało 580 znaków

2018-06-08 11:00

Rejestracja: 2 lata temu

Ostatnio: 10 miesięcy temu

0

Mam pewne wskazówki, powinny pomóc ruszyć do przodu:

na linii 81 należałoby zamienić $_FILES["upload_file"]["name"] na $_FILES["upload_file"]["tmp_name"] - tutaj znajduje się prawidłowa ścieżka do pliku, który jest uploadowany. $_FILES["upload_file"]["name"] wskazuje jedynie nazwę pliku przesyłanego.

Walidacja zwraca błędy oraz nie ma treści w mailu, ponieważ funkcja prepare_data nie zwraca wartości - trzeba je ręcznie zwracać, return nie zrobi się automatycznie.

Pozostało 580 znaków

2018-06-08 11:35

Rejestracja: 4 lata temu

Ostatnio: 6 godzin temu

Lokalizacja: Piwnica

1

tylko po co sie tak szarpać, phpmailer, albo jakiś prosty framework i masz wszystko out of the box z walidacją, sanityzacją, komunikatami itp.


Pozostało 580 znaków

2018-06-08 14:17

Rejestracja: 2 lata temu

Ostatnio: 10 miesięcy temu

0

Zgadzam się, gotowe skrypty są bardzo pomocne. PHPmailer jest biblioteką, która załatwia za nas cały trud wysyłki maili, ale czasem jednak warto poznać jak to działa - wtedy można się dużo nauczyć ;)

Pozostało 580 znaków

Polak
2018-06-16 19:27
Polak
0

Wszystko elegancko, ale mimo wszystko chciałbym ćwiczeniowo to napisać od zera. ;)

Pozostało 580 znaków

Polak
2018-06-16 19:36
Polak
0

Przerobiłem skrypt nieco, aby go maksymalnie uprościć. Wyrzuciłem walidację, zminimalizowałem liczbę pól formularza etc.

<!DOCTYPE HTML>

<?php
/*
1. Po kliknięciu wyślij ma leciec mail do mnie.
2. Schemat tematu wiadomości np. Problem/$licznik/$date
gdzie $licznik to będzie zmienna zwiększana po każdym wysłaniu maila
3. Dodawanie załącznika/pliku graficznego do formularza i wysyłanie go potem.
4. Walidacja żeby głupot nie wpisywali.
5. Zapisywanie do bazy danych wysłanych mailem informacji.
6. Rozmiar pliku nie większy niż 2MB.
*/

/*
tabela w bazie
CREATE TABLE IF NOT EXISTS `mail_counter` (
  `counter` int(255) NOT NULL
);

*/

    try{
        $dbconn = new PDO('mysql:host=localhost;dbname=test', 'root', 'epkzpakf');      
    } catch (PDOException $e){
        print "Błąd połączenia z bazą: " . $e->getMessage() . "<br/>";
        die();
    }
    $query = "SELECT * FROM mail_counter";
    $row = $dbconn->query($query);
    //$mailCount = $row["counter"]; czy to jest potrzebne do czegoś?

    $formErrors = array(
        "name" => array(
            "error" => "Należy podać imię.",
            "error2" => "Należy wpisywać litery."
        ),
        "surname" => array(
            "error" => "Należy podać nazwisko.",
            "error2" => "Należy wpisywać litery."
        ),
        "company" => array(
            "error" => "Należy podać nazwę firmy.",
            "error2" => "Należy wpisywać litery."
        ),
        "email" => array(
            "error" => "Należy podać email kontaktowy.",
            "error2" => "Należy podać poprawny email. Będzie użyty do kontaktu zwrotnego."
        ),
        "comment" => array(
            "error" => "Należy opisać problem.",
        ),
        "upload_file" => array(
            "error" => "Dozwolone są tylko obrazki w formatach JPG, PNG, JPEG.",
            "error2" => "Plik jest większy niż 2MB.",
            "error3" => "Wystąpił problem z dołączeniem pliku:"
        )
    );

/*  #usuwanie niepotrzebnych znaków w razie jakby miały się pojawić
    function prepare_data($form_data) {
        $form_data = trim($form_data); #skasowanie białych znaków
        $form_data = stripslashes($form_data); #kasowanie backslashy
        return $form_data;
    }

    //do wyrzucenia niepotrzebne zmienne
    $nameErr = $surnameErr = $companyErr = $emailErr = $commentErr = $upload_fileErr = "";
    $name = $surname = $company = $email = $comment = $upload_file = $mailMsg = $headers = $body = $content = "";
    $counter = 0;

        if (isset($_POST["name"])) {
            $name = prepare_data($_POST["name"]);
            if (!preg_match("/^[a-zA-Z]$/", $name)){
                $formErrors["name"]["error2"];
            }
        }

        if (isset($_POST["surname"])) {
            $surname = prepare_data($_POST["surname"]);
            if (!preg_match("/^[a-zA-Z]$/", $surname)){
                $formErrors["surname"]["error2"];
            }
        }

        if (isset($_POST["company"])) {
            $company = prepare_data($_POST["company"]);
            if (!preg_match("/^[a-zA-Z]$/", $company)){
                $formErrors["company"]["error2"];
            }
        }

        if (isset($_POST["email"])) {
            $email = prepare_data($_POST["email"]);
            if (!filter_var($email, FILTER_VALIDATE_EMAIL)){
                $formErrors["email"]["error2"];
            }
        }

        if (isset($_POST["comment"])) {
            $comment = prepare_data($_POST["comment"]);
        }

*/  

    if (isset($_POST) && !empty($_POST)){
        $counter = 0;
        $file_name = $temp_name = $file_type = "";
        if(!empty($_FILES['upload_file']['name'])) {
            $file_name = $_FILES['upload_file']['name'];
            $temp_name = $_FILES['upload_file']['tmp_name'];
            $file_type = $_FILES['upload_file']['type'];
            $upload_folder = "./tmp_dir/";

            move_uploaded_file($_FILES['upload_file']['tmp_name'], $upload_folder.$_FILES['upload_file']['name']);

            $base = basename($file_name);
            $extension = strtolower(pathinfo($base, PATHINFO_EXTENSION));
            $allowed_extensions = array("jpg", "jpeg", "png");

            if(in_array($extension, $allowed_extensions)) {
                $from = $_POST['email'];
                $toEmail = "[email protected]";
                $date = date('Y-m-d h:i:sa');
                $subject = "Problem/$counter/$date";
                $message = $_POST['email']; //dodać w formularzu text area i zmienic tu na comment

                //$file = $temp_name;
                $content = chunk_split(base64_encode(file_get_contents($file_name)));
                $uid = md5(uniqid(time()));

                $header = "From: ".$from."\r\n";
                $header .= "Reply-To: ".$toEmail."\r\n";
                $header .= "MIME-Version: 1.0\r\n";
                $header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"\r\n\r\n";
                $header .= "Mime multipart message.\r\n";

                $header .= "--".$uid."\r\n";
                $header .= "Content-Type:text/plain; charset=iso-8859-1\r\n";
                $header .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
                $header .= $message."\r\n\r\n";

                $header .= "--".$uid."\r\n";
                $header .= "Content-Type: ".$file_type."; name=\"".$file_name."\"\r\n";
                $header .= "Content-Transfer-Encoding: base64\r\n";
                $header .= "Content-Disposition: attachement; filename=\"".$file_name."\"\r\n\r\n";
                $header .= $content."\r\n\r\n";

                if (mail($toEmail, $subject, "", $header)) {
                    echo "Mail został wysłany.";
                    $query = "UPDATE mail_counter SET counter = ++$counter";
                    $dbconn->query($query);
                } else {
                    echo "Nie udało się wysłać maila.";
                }
                exit;

            } else {
                echo $formErrors["upload_file"]["error"];
            }

        } else {
            echo $formErrors["upload_file"]["error3"];
        }
    }   

?>
<html>
    <head>
        <title>HelpDesk - wyślij problem</title>
        <style>
            .error {
                color: #FF0000;
            }
            .mailmsg {
                color: #00ddff;
            }
        </style>
    </head>
<body>
    <p><span class="error">* wymagane pola</span></p>

    <form method="post" action="helpdesk_forum.php" enctype="multipart/form-data">
        <label for="email">Email:<span class="error">*</span></label> 
        <input type="text" name="email"><br>
        <label for="upload_file">Wybierz plik do podesłania:</label><br> 
        <input type="file" name="upload_file">
        <input type="submit" name="submit" value="Wyślij">
    </form>

</body>
</html>

Pozostało 580 znaków

Polak
2018-06-16 19:40
Polak
0

Z rozpędu wcisnąłem "enter" i post się wysłał...

A propos kodu z poprzedniego posta:

  • dodałem move_uploaded_file, bo wyczytałem, że to lepsze podejście niż użycie "is_uploaded_file" i potem użycie "copy"; poza tym jest to wymagane przy dodawaniu załącznika
  • błędy są w tablicy
  • dodane połączenie do bazy w celu zwiększania licznika po wysyłce maili (na razie nieweryfikowalne, bo mail się nie wysyła)
  • odrobinę przerobiłem headery

Pozostało 580 znaków

Polak
2018-06-16 20:32
Polak
0

wygoglowałem, że można dump robić używając var_dump(), więc dodałem:

var_dump($_FILES['upload_file']['tmp_name']);
die();

zaraz powyżej $content = chunk_split(base64_encode(file_get_contents($file_name)));
niezależnie czy dodawany plik "obraz.jpg" jest w pobranych itp. czy w htdocs wraz ze skryptem, to zwraca mi:
string(0) ""

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0