[php] mail en (sub)parts

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
ik heb een mailprogramma geschreven wat goed werkte totdat er een mail binnenkwam waarbij er meerdere subparts waren. Er waren zeg maar 2 gedeeltes: 1 tekst en 1 wat een plaatje was, en het eerste gedeelte bevatte een text/plain gedeelte en een text/html gedeelte.
Het lukt me nu in princiepe prima om dat allemaal te onderscheiden van elkaar en weer te geven, maar vraag me nu af waar ik nog allemaal meer tegen aan ga lopen.

toen ik met die mail-client begon heb ik een tutorial van phpbuilder doorgelezen om een indruk te krijgen hoe hij het gedaan had. In zijn code hield hij er ook rekening mee dat sommige gedeeltes tekst waren en andere attachments. De tekstgedeeltes werden in dat voorbeeld allemaal aan elkaar geplakt en de attachments weggeschreven naar een bestand.
Het is echter zo dat een mail soms zo vertuurd wordt dat je een tekst en een html gedeelte heb die qua content (het bericht opzich) identiek zijn. Nou is het natuurlijk niet de bedoeling dat die twee gedeeltes aan elkaar worden geplakt, maar dat je maar 1 van beide weergeeft. Omdat ik alles in een database opsla wil ik dan gewoon een tekst en een html versie op slaan.
Punt is nu alleen dat ik wel heel veel informatie kan vinden over het versturen van een tekst en html versie, maar dat ik niet echt kan vinden wat de regel hiervoor is. Die kan ik wel afleiden uit hoe je het moet versturen, maar zijn er ook nog andere dingen mogelijk. Zoals ik het nu alleen nog maar ben tegengekomen is zoals ik in het eerste voorbeeld noemde: part 1 bestaat uit 1.1 (tekst) en 1.2 (html), eventuele plaatjes of attachments zitten in > 2(.x). Maar die pipo van die tutorial hield er ook rekening mee dat er verderop in de email eventueel nog meerdere gedeeltes zaten die wellicht ook tot het bericht hoorde. Kan dat inderdaad? En kunnen dat opzich ook weer 2 dezelfde berichten zijn, 1 in tekst en de ander in html?

Ik hoop dat mijn vraag duidelijk is, ik vind het een beetje lastig uit te leggen.

Acties:
  • 0 Henk 'm!

  • Eskimootje
  • Registratie: Maart 2002
  • Laatst online: 08:29
Je kan ook nog plaatjes versturen die in de mail thuishoren alleen krijg je dan volgens mij zoiets:

1.1 Tekst

1.2.1 HTML
1.2.2 Plaatje

2.1 Bijlage die niet horen bij mail


http://www.zend.com/zend/spotlight/sendmimeemailpart1.php daar staat ook veel over het mimi-formaat.

Acties:
  • 0 Henk 'm!

Verwijderd

ik weer ;)
Punt is nu alleen dat ik wel heel veel informatie kan vinden over het versturen van een tekst en html versie, maar dat ik niet echt kan vinden wat de regel hiervoor is.
Ik denk dat je het beste kan beginnen met het lezen van RFC's. Dit is misschien wel wat veel, maar hier staat echt veel nuttige informatie in, zowel voor als je mail gaat ontleden als voor mail versturen/samenstellen.

RFC 2045 - Multipurpose Internet Mail Extensions I
RFC 2046 - Multipurpose Internet Mail Extensions II
RFC 2047 - Multipurpose Internet Mail Extensions III
RFC 2048 - Multipurpose Internet Mail Extensions IV

Uiteraard zul je niet alles nodig hebben, maar kijk er eens naar :)

;)

Acties:
  • 0 Henk 'm!

  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
beide bedankt voor de linkjes.
Ik snap 'm nu in princiepe helemaal. alles is duidelijk ook hoe het zit met embedden van plaatjes in email e.d.
Het enige is dat ik nog niet ergens zwart op wit heb kunnen vinden dat het bericht van een email als het ware gefragmenteerd mag zijn of niet. Ik vind het namelijk zo typisch dat die gast uit die tutorial die ik gelezen heb daar namelijk rekening mee hield. maar als ik die linkjes van jullie doorlees, dan komt dat dus eigenlijk nooit voor? (mag niet eens?) en kun je er van uit gaan dat als er een text-gedeetle en een html gedeelte (of enriched text) is, dat die hetzelfde bericht bevatten en dat je verderop niet nog gedeeltes heb die nog brokken bevatten wat ook nog bij het bericht hoort.

Acties:
  • 0 Henk 'm!

  • Eskimootje
  • Registratie: Maart 2002
  • Laatst online: 08:29
Je hebt dit: Content-Type: multipart/alternative; en Content-Type: multipart/mixed;

De alternative zorgt ervoor dat delen gescheiden worden terwijl de mixed zegt dat ze bij elkaar horen. Als er dus iets word gescheiden krijg je 2 delen in het ene deel kun je dus meerdere stukken samen plakken van het mixed type. Maar die kunnen nooit bij het andere al gesplitte gedeelte komen. Als het niet duidelijk is wil ik zo wel even een paint poging doen.

Acties:
  • 0 Henk 'm!

  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
ik heb nu de volgende class gemaakt:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
class disectMail
{
     // message types
    var $type = array(
                "text",
                "multipart",
                "message",
                "application",
                "audio",
                "image",
                "video",
                "other");
     // message encodings
    var $encoding = array(
                "7bit",
                "8bit",
                "binary",
                "base64",
                "quoted-printable",
                "other");

    var $body       = array();
    var $attachments    = array();
    var $a_index        = 0;

    function disectMail($inbox, $x)
    {
        $i = 1;
        while ($fetchbody = imap_fetchbody($inbox, $x, $i))
        {
            $this->parsePart(imap_bodystruct($inbox, $x, $i), $fetchbody);
            $j = 1;
            while($fetchbody = imap_fetchbody($inbox, $x, $i.".".$j))
            {
                $this->parsePart(imap_bodystruct($inbox, $x, $i.".".$j), $fetchbody);
                $j++;
            }
            $i++;
        }
    }

    function parsePart($bodystruct, $fetchbody)
    {
        $type       = $this->type[$bodystruct->type];
        $subtype    = $bodystruct->subtype;
        $encoding   = $this->encoding[$bodystruct->encoding];

        if ($bodystruct->ifdisposition == 1)
            $disposition    = $bodystruct->disposition;
        elseif (isset($disposition))
        {
             // ifdisposition must be 0, we unset any previously set disposition
            unset($disposition);
        }

         // if true, this is a message and we need to display it
        if (($type == "text" || $type == "message") && !isset($disposition))
        {
            if (strtolower($subtype) == "html")
                $this->body['html'] = $this->decode($fetchbody, $encoding);
            else
                $this->body['text'] = $this->decode($fetchbody, $encoding);
        }
        elseif (isset($disposition))
        {
            $params = $bodystruct->dparameters;
            foreach ($params as $p)
            {
                if($p->attribute == "FILENAME")
                {
                    $this->attachments[$this->a_index++]["name"] = $p->value;   
                    break;          
                }
            }
        }
        elseif($type != "multipart")
        {
             // must be image, application, or sound
            if ($fp = fopen("temp/".$bodystruct->id, "w+"))
            {
                fputs($fp, $this->decode($fetchbody, $encoding));
                fclose($fp);
            }
        }
    }

    function decode($string, $enc)
    {
        switch($enc)
        {
            case "quoted-printable":
                $output = imap_qprint($string);
                break;
            case "base64":
                $output = imap_base64($string);
                break;
            default:
                $output = $string;
                break;
        }
        return $output;
    }
}


Ik programmeer eigenlijk nooit OO, dus het ziet er misschien een beetje raar uit. Maar het leek me in dit geval wel handig om toch maar te maken.
De attachments doe ik op dit moment nog niets mee, maar op die plaats ga ik ze wegschrijven naar een bestand; de embedded images/etc, doe ik ook nog weinig mee (behalve ff naar een tijdelijke dir wegschrijven), maar die ga ik nog even netjes naar een bestand wegschrijven. De bedoeling is dat ik dan nog een replace uitvoer op het html-gedeelte van het bericht (als die er is), waarbij ik cid:[id] vervang voor de locatie en naam van het plaatje/geluidje.

Het enige wat ik me nu nog afvroeg is of een email ook dieper kan gaan dan 1 level met subparts (dus 1.3.1 ofzo), want daar houdt mijn class geen rekening mee. Er werd ook niet echt over gesproken bij die linkjes die ik eerder van jullie heb gekregen (of ik moet er overheengelezen hebben)

[ Voor 10% gewijzigd door marty op 27-08-2003 15:46 ]


Acties:
  • 0 Henk 'm!

Verwijderd

[beetje offtopic]
Misschien is dit ook leuk om naar te kijken: HtmlMimeMail
[/beetje offtopic]

Acties:
  • 0 Henk 'm!

  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
thnx for the link, maar het versturen gaat al perfect ;)

  • stekkel
  • Registratie: Augustus 2001
  • Laatst online: 17-09 08:05
Voor alle mail gerelateerde RFC's en drafts zou je eens moeten kijken op http://www.imc.org

Met alleen de MIME RFC's ben je er namelijk nog niet.

  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
marty schreef op 27 August 2003 @ 15:44:

Het enige wat ik me nu nog afvroeg is of een email ook dieper kan gaan dan 1 level met subparts (dus 1.3.1 ofzo), want daar houdt mijn class geen rekening mee.
Goed, na een zo ingewikkeld mogelijke email in elkaar te hebben geflansed bleek dat dat inderdaad kan en dat die functie dus recursief gemaakt moest worden.

Ik heb dat als volgt gedaan:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function disectMail($inbox, $x, $p=1)
{
    while ($fetchbody = imap_fetchbody($inbox, $x, $p))
    {
        if(eregi("\.", $p))
        {
            $j = substr(strrchr($p, "."), 1);
            $i = substr($p, 0, -(strlen($j)+1));
            $q = $i.".".($j + 1);
        }
        else
        {
            $q = ($p + 1);
        }

        $this->parsePart(imap_bodystruct($inbox, $x, $p), $fetchbody);
        while($check = imap_fetchbody($inbox, $x, $p.".1"))
        {
            $this->disectMail($inbox, $x, $p.".1");
        }
        $p = $q;
    }
}
wat de functie doet is kijken of er een subpart van het huidige deel is, door er .1 achter te plakken, en zo nee dan wordt het huidige deel met 1 (sub)deel opgehoogd (1 wordt 2; 1.1 wordt 1.2 etc)

Het gekke is alleen dat ie blijft hangen na 1.1.2
Om het te debuggen heb ik er even deze functie van gemaakt:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function disectMail($inbox, $x, $p=1)
{
    while ($fetchbody = imap_fetchbody($inbox, $x, $p))
    {
        if(eregi("\.", $p))
        {
            $j = substr(strrchr($p, "."), 1);
            $i = substr($p, 0, -(strlen($j)+1));
            $q = $i.".".($j + 1);
        }
        else
        {
            $j = "";
            $i = "";
            $q = ($p + 1);
        }
        echo "p:".$p." - q:".$q." - i:".$i." - j:".$j."<br>\n";
        flush();
        $this->parsePart(imap_bodystruct($inbox, $x, $p), $fetchbody);
        while($check = imap_fetchbody($inbox, $x, $p.".1"))
        {
            $this->disectMail($inbox, $x, $p.".1");
        }
        $p = $q;
        echo "p is bij de volgende ".$p."<br>\n";
    }
}

Dit geeft als output:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
p:1 - q:2       - i:    - j:
p:1.1   - q:1.2     - i:1   - j:1
p:1.1.1 - q:1.1.2   - i:1.1 - j:1
p is bij de volgende 1.1.2

p:1.1.2 - q:1.1.3   - i:1.1 - j:2
p is bij de volgende 1.1.3

p:1.1.1 - q:1.1.2   - i:1.1 - j:1   <= gaat fout, p moet 1.1.3 zijn
p is bij de volgende 1.1.2

p:1.1.2 - q:1.1.3   - i:1.1 - j:2
p is bij de volgende 1.1.3

p:1.1.1 - q:1.1.2   - i:1.1 - j:1   <= gaat fout, p moet 1.1.3 zijn
p is bij de volgende 1.1.2

Heel vreemd, van 1.1.1 naar 1.1.2 gaat goed. P neemt aan het einde van die while de waarde 1.1.3 aan, maar vervolgens springt ie weer op 1.1.1 :? :?
Ik zal vast wel iets heel stoms over het hoofd zien, maar ik ben nu al ruim een uur bezig met debuggen en ik zie het echt niet...

wie ziet wat ik fout doe?
Pagina: 1