Autor Zpráva
Pavel777
Profil *
Zdravím všechny - mám tu zajímavý problém.
Přechodem na PHP 5.3 začal PHPMailer zalamovat text ve zprávě (html i plain) naprosto špatně. Zalomí dokonce i v polovině utf8 znaku a ten se pak nezobrazí. Změna $mail->WordWrap nedělá nic - výsledek je pořád stejnej.

Nevíte někdo co s tím? Na netu jsem nikde nic nenašel. Zkouším PHPMailer 5.1 i 5.2 na PHP 5.3.6-pl1-gentoo.

Díky, Pavel
Davex
Profil
Pavel777:
Již dlouho používám PHPMailer (nyní verzi 5.2.1) s PHP 5.3.3 a tento problém jsem ještě nepozoroval. Když se podívám do zdrojového kódu zpráv odeslaných v UTF-8, tak se text nikdy nezalamuje uprostřed slova.

Můžeš ukázat tvůj odesílací kód, aby se dala chyba otestovat jinde?
Pavel777
Profil *
Tak tohle mi na PHP 5.2 funguje v pohodě. Z databáze beru text body i altBody - utf8.
<?php

include_once('../class.phpmailer.php');
require_once('../class.html2text.inc');

$mail = new PHPMailer(); // defaults to using php "mail()"

$mail->SetLanguage("cz", "/language/");
$mail->Encoding = "quoted-printable";
$mail->CharSet = "utf-8";
// $mail->WordWrap = 0;                              // nedělalo nic i když jsem dal 150, zalamovalo se stejně

// zpráva
$sql = "SELECT subject, body, altbody FROM news WHERE id = $newsletterID";
$conn = funkce_na_pripojeni($sql);

pg_exec($conn, "SET DATESTYLE TO GERMAN");

$result = pg_exec($sql);
$myrow = pg_fetch_assoc($result);
$body = $myrow['body'];                    //$body = eregi_replace("[\]",'',$body); dělat?????????
$altBody = $myrow['altbody'];        // možnost dát do db pro altbody něco jinýho

if ($altBody == "") {                        // v db nic udělám z html
//    $h2t =& new html2text($body);  // tohle mi v PHP 5.3 taky nejde (reference), dal jsem pryč
//    $altBody = $h2t->get_text();
//    $altBody = ltrim($altBody);   // jinak na začátku odřádkuje a dokonce dává tab
//    $altBody = rtrim($altBody);   // na konci za ukončovací tagy dával mezery
//    $altBody = str_replace("  ", " ", $altBody); // před a za obrázkem nechával 2 mezery
}

$mail->Subject = $myrow['subject'];
$mail->AltBody = $altBody;
$mail->MsgHTML($body);
$mail->From = "xxxx@xxxxxx.cz";
$mail->FromName = "xxx xxx";

// cestak obrázkům z id newsletteru 0001 atd
$format = "../../../images/newsletters/%04d/";
$path = sprintf($format, $newsletterID);

$sql = "SELECT i_name, mime_type FROM images WHERE newsletter = $newsletterID";
$result = pg_exec($sql);

// Přidáme obrázky do mailu.
for ($i = 0; $i < PG_NumRows($result); $i++) {
    $record = PG_Fetch_Array($result, $i);
    if (!$mail->AddEmbeddedImage($path.$record["i_name"], $record["i_name"], $record["i_name"], "base64", $record["mime_type"])) {
        echo 'Soubor '.$path.$record["i_name"].' nenalezen';
        pg_close($conn);
        exit;
    }
}

$date;
$time;
$sent = 0;
$sql = "SELECT moves.id, persons.p_name, persons.email, firms.f_name FROM moves, persons, firms WHERE moves.person = persons.id AND persons.firm = firms.id AND moves.newsletter = $newsletterID AND moves.sent isnull ORDER BY moves.id DESC";
$result = pg_exec($sql);

// odesílání na jednotlivý adresy - cyklus
for ($i = 0; $i < PG_NumRows($result); $i++) {
    if ($sent > $set - 1)
        break;

    $record = PG_Fetch_Array($result, $i);
    $email = $record["email"];
    $email = rtrim($email);

    if ($email == "")        // v db můžou být záznamy bez mailu - nechávám pro doplnění
      continue;                     // neukládám pro ně do moves, ale pro jistotu

    $alias = $record["p_name"];   // zobrazované jméno může být v db prázdné
    if ($alias == "")
        $alias = $record["f_name"]; // pak dám název organizace

    $mail->AddAddress($email, $alias);

    $ret = $mail->Send(); // hlavní odeslání

    $date = date("Y-m-d H:i:s", time());  // datum a čas odeslání zprávy pro DB
    $time = date("H:i:s", time());  // čas - jen pro zprávu na konci

    if(!$ret) {
        echo "Mailer Error: ".$mail->ErrorInfo;
        pg_close($conn);
        exit;
    }
    else {
        $sent++;
        $mail->ClearAddresses(); // při dalším průchodu mi chodilo pořád na mail 1
        $movesId = $record["id"];
        $sql = "UPDATE moves SET sent = '$date' WHERE id = $movesId";
        $res = pg_exec($sql);
        if (!$res) {
            echo "Nezapsalo se odeslání zrávy do databáze";
            pg_close($conn);
            exit;
        }
    }
}

if ($sent) {
    echo "Počet odeslaných zpráv = $sent - $time<br><br>"."\n";
    echo "Odeslána skupina = $opened/$limit<br>"."\n";
}
else
    echo "Počet odeslaných zpráv = 0";

pg_close($conn);

?>
Davex
Profil
Pavel777:
Dělá to pouze v kódování quoted-printable, které už nikde nepoužívám, a jen v některých programech. Třeba takový Outlook Express s tím problémy nemá.

Vypadá to spíš na chybu dekodéru, který si neporadí se zlomem řádku mezi kódovanými bajty znaku v UTF-8. Nebyl by s tím problém, kdyby dekodér nejdřív odstranil řádkování a pak teprve dekódoval.

Problém je způsoben tím, že od PHP 5.3 používá PHPMailer pro zakódování quoted-printable nativní funkci quoted_printable_encode(), která text kóduje trochu jinak než funkce obsažená v PHPMaileru a nezabývá se používaným kódováním textu.

Chyba by se měla dát odstranit tak, že se zakomentují v souboru class.phpmailer.php, v metodě EncodeQP() řádky 1875 až 1877 (pro PHPMailer 5.2.1).
pavel777
Profil *
Davex:
Ahoj, base64 - super nápad. Nepoužl jsem to jen, že je ve zdroji líp vidět o co jde a mail je menší, ale je to zbytečný.
Já se vždycky raději přikláním používat tyto věci vbez vlastích úprav, protože pak změním verzi a zase musím dělat změny. Tady to ale stejně nebude jednoduchý. Používám 5.1 pro skladbu těla mime zprávy a vložený inline obrázek. Z 5.1 se mi to zobrazí správně v Outlookách, web mail klientech (seznamu, icewqrp...) ale i na mobilech (Windows mobile a iPhone). Když jsem použil PHPMailer 5.2 změna v pořadí (zanoření) boundries způsobila že na WM 6.5, obrázek ve zprávě prostě nezobrazím. 5.2 mi dokonce napsal, že nelze instatntiate class a nenašel jsem čas se tím hlouběji zabývat. Už takto jsem na tomhle maileru nechal času až hrůza. Uvažuji o mailování z nette - vypadá to tam o dost líp. Díky. Pavel
Davex
Profil
pavel777:
Dnes už se nebojím používat pro tělo zprávy 8 bitové kódování. Pokud je podporováno odesílacím mailserverem, tak s tím nebývají problémy a případnou nepodporu 8BITMIME v cestě k příjemci si dokážou mailservery vyřešit mezi sebou.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: