source: spip-zone/_plugins_/facteur/inc/facteur_classes.php @ 28930

Last change on this file since 28930 was 28345, checked in by pierre.basson@…, 12 years ago

facteur 1.1 : test version compatible php4

  • Property svn:executable set to *
File size: 12.9 KB
Line 
1<?php
2
3
4        if (intval(phpversion()) == 5) {
5                include_spip('phpmailer-php5/class.phpmailer');
6                include_spip('phpmailer-php5/class.smtp');
7        } else {
8                include_spip('phpmailer-php4/class.phpmailer');
9                include_spip('phpmailer-php4/class.smtp');
10        }
11        include_spip('facteur_fonctions');
12
13        class Facteur extends PHPMailer {
14
15                function Facteur($email, $objet, $message_html, $message_texte) {
16
17                        if ($GLOBALS['meta']['facteur_adresse_envoi'] == 'oui') {
18                                $this->From             = $GLOBALS['meta']['facteur_adresse_envoi_email'];
19                                $this->FromName = $GLOBALS['meta']['facteur_adresse_envoi_nom'];
20                        } else {
21                                $this->From             = $GLOBALS['meta']['email_webmaster'];
22                                $this->FromName = $GLOBALS['meta']['nom_site'];
23                        }
24
25                        $this->CharSet  = $GLOBALS['meta']['charset'];
26                $this->Mailer   = 'mail';
27                        $this->Subject  = $objet;
28                        $this->AddAddress($email);
29
30                        if (isset($GLOBALS['meta']['facteur_smtp_sender'])) {
31                        $this->Sender = $GLOBALS['meta']['facteur_smtp_sender'];
32                        $this->AddCustomHeader("Errors-To: ".$this->Sender);
33                        }
34
35                        if (isset($GLOBALS['meta']['facteur_smtp']) AND $GLOBALS['meta']['facteur_smtp'] == 'oui') {
36                        $this->Mailer   = 'smtp';
37                            $this->Host         = $GLOBALS['meta']['facteur_smtp_host'];
38                            $this->Port         = $GLOBALS['meta']['facteur_smtp_port'];
39                                if ($GLOBALS['meta']['facteur_smtp_auth'] == 'oui') {
40                                    $this->SMTPAuth = true;
41                                    $this->Username = $GLOBALS['meta']['facteur_smtp_username'];
42                                    $this->Password = $GLOBALS['meta']['facteur_smtp_password'];
43                                } else {
44                                    $this->SMTPAuth = false;
45                                }
46                                if (intval(phpversion()) == 5) {
47                                        if ($GLOBALS['meta']['facteur_smtp_secure'] == 'ssl')
48                                            $this->SMTPSecure = 'ssl';
49                                        if ($GLOBALS['meta']['facteur_smtp_secure'] == 'tls')
50                                            $this->SMTPSecure = 'tls';
51                                }
52                        }
53
54                        if (!empty($message_html)) {
55                        $this->Body = $message_html;
56                        $this->IsHTML(true);
57                                if ($GLOBALS['meta']['facteur_filtre_css'])
58                                        $this->ConvertirStylesEnligne();
59                                if ($GLOBALS['meta']['facteur_filtre_images'])
60                                        $this->JoindreImagesHTML();
61                        }
62                        if (!empty($message_texte)) {
63                                if (!$this->Body) {
64                                        $this->IsHTML(false);
65                                        $this->Body = $message_texte;
66                                } else {
67                                        $this->AltBody = $message_texte;
68                                }
69                        }
70
71                        if ($GLOBALS['meta']['facteur_filtre_iso_8859'])
72                                $this->ConvertirUtf8VersIso8859();
73
74                }
75
76
77                function JoindreImagesHTML() {
78                        $image_types = array(
79                                                                'gif'   => 'image/gif',
80                                                                'jpg'   => 'image/jpeg',
81                                                                'jpeg'  => 'image/jpeg',
82                                                                'jpe'   => 'image/jpeg',
83                                                                'bmp'   => 'image/bmp',
84                                                                'png'   => 'image/png',
85                                                                'tif'   => 'image/tiff',
86                                                                'tiff'  => 'image/tiff',
87                                                                'swf'   => 'application/x-shockwave-flash'
88                                                        );
89                        while (list($key,) = each($image_types))
90                                $extensions[] = $key;
91
92                        preg_match_all('/"([^"]+\.('.implode('|', $extensions).'))"/Ui', $this->Body, $images);
93
94                        for ($i=0; $i<count($images[1]); $i++) {
95                                if (file_exists('../'.$images[1][$i])) {
96                                        $html_images[] = '../'.$images[1][$i];
97                                        $this->Body = str_replace($images[1][$i], basename($images[1][$i]), $this->Body);
98                                }
99                                if (file_exists($images[1][$i])) {
100                                        $html_images[] = $images[1][$i];
101                                        $this->Body = str_replace($images[1][$i], basename($images[1][$i]), $this->Body);
102                                }
103                        }
104
105                        $images = array();
106                        preg_match_all("/'([^']+\.(".implode('|', $extensions)."))'/Ui", $this->Body, $images);
107
108                        for ($i=0; $i<count($images[1]); $i++) {
109                                if (file_exists('../'.$images[1][$i])) {
110                                        $html_images[] = '../'.$images[1][$i];
111                                        $this->Body = str_replace($images[1][$i], basename($images[1][$i]), $this->Body);
112                                }
113                                if (file_exists($images[1][$i])) {
114                                        $html_images[] = $images[1][$i];
115                                        $this->Body = str_replace($images[1][$i], basename($images[1][$i]), $this->Body);
116                                }
117                        }
118
119                        if (!empty($html_images)) {
120                                $html_images = array_unique($html_images);
121                                sort($html_images);
122                                for ($i=0; $i<count($html_images); $i++) {
123                                       
124                                        // Bug Fix: dans thunderbird, il faut etre strict avec le header envoy� avec l'image
125                                        $bouts = explode(".", basename($html_images[$i]));
126                                $extension = strtolower(array_pop($bouts));
127                                $header_extension = $image_types[$extension];
128                                       
129                                        $cid = md5(uniqid(time()));
130                                        $this->AddEmbeddedImage($html_images[$i], $cid, basename($html_images[$i]),'base64',$header_extension);
131                                        $this->Body = str_replace(basename($html_images[$i]), "cid:$cid", $this->Body);
132                                }
133                        }
134                }
135
136
137                function ConvertirStylesEnligne() {
138                        /*
139
140                        Written by Eric Dols - edols@auditavenue.com
141
142                        You may freely use or modify this, provided
143                        you leave credits to the original coder.
144                        Feedback about (un)successfull uses, bugs and improvements done
145                        are much appreciated, but don't expect actual support.
146
147                        PURPOSE OF THIS FUNCTION
148                                It is designed to process html emails relying
149                                on a css stylesheet placed in the <head> for layout in
150                                order to enhance compatibility with email clients,
151                                including webmail services.
152                                Provided you use minimal css, you can keep styling separate
153                                from the content in your email template, and let this function
154                                "inject" those styles inline in your email html tags on-the-fly,
155                                just before sending.
156                                Technically, it grabs the style declarations found in the
157                                <head> section and inserts each declaration inline,
158                                inside the corresponding html tags in the email message.
159
160                                Supports both HTML and XHTML markup seamlessly. Thus
161                                tolerant to email message writers using non-xhtml tag,
162                                even when template is xhtml compliant (e.g. they would
163                                add <img ...> instead of a xhtml compliant <img ... />).
164
165                        NEW 10 dec. 2003:
166                                - code revised, including a few regexp bugs fixed.
167                                - multiple class for a tag are now allowed <p class="firstclass secondclass">
168                                - all unsupported css styles are now moved to the body section (not just a:hover etc...)
169
170                        USE
171                                Add this function to a function library include, like "inline.inc"
172                                and include it near the beginning of your php page:
173                                require ("inline.inc");
174
175                                load the html source of message into a variable
176                                like $html_source and process it using:
177                                $html_source = sheet2inline($html_source)
178
179
180                        STYLE DEFINITIONS SUPPORTED
181                                TAG { ... }
182                                TAG1, TAG2, ... { ... }
183                                TAG.class { ... }
184                                .class { ...)
185                                TAG:pseudo { ... }
186
187
188                                CSS definitions may be freely formatted (spaces, tabs, linefeeds...),
189                                they are converted to oneliners before inserting them inline in the html tags.
190
191                                .class definitions are processed AFTER tag definitions,
192                                thus appended inline after any existing tag styling to
193                                preserve the normal css priority behavior.
194
195                                Existing style="..." attributes in tags are NOT stripped. However they MUST
196                                be with double quotes. If not, an addtional style="..." attribute will be added
197
198
199                        KNOWN LIMITATIONS
200                                - style info should be placed in <head> section. I believe
201                                  it shouldnt be too hard to modify to point to an external
202                                  stylesheet instead.
203                                - no support (yet?):
204                                  * chains like P UL LI { .... } or P UL LI.class { .... }
205                                  * #divname p { ... } and <tag id="...">
206                                  * a:hover, a:visited {...} multiple class:pseudo
207                                  They require a significantly more complicated processing likely
208                                  based on stylesheet and document trees parsing.
209                                  Many email clients don't handle more than what is supported
210                                  by this script anyway.
211                                - pseudo-classes like a:hover {...} can't be inserted inline
212                                  in the html tags: they are moved to a <style> declaration in
213                                  the <body> instead. This is a limitation from html, not this script.
214                                - It is still up to you to check if target email clients render
215                                  your css styled templates correctly, especially webmail services
216                                  like Hotmail, in which the email becomes a sub-part of an html page,
217                                  with styles already in place.
218                        */
219
220                        // variables to be accessed in the callback sub-function too
221                        global $styledefinition, $styletag, $styleclass;
222
223                        // Let's first load the stylesheet information in a $styles array using a regexp
224                        preg_match_all ( "/^[ \t]*([.]?)([\w, #]+)([.:])?(\S*)\s+{([^}]+)}/mi", $this->Body , $styles);
225                        /*
226                                $styles[1] = . or ''  => .class or tag (empty)
227                                $styles[2] = name of class or tag(s)
228                                $styles[3] = : . or '' => followed by pseudo-element, class separator or nothing (empty)
229                                $styles[4] = name of pseudo-element after a tag, if any
230                                $styles[5] = the style definition itself, i.e. what's between the { }
231                        */
232
233                        // Now loop through the styles found and act accordingly;
234
235                        // process TAG {...} & TAG1, TAG2,... {...} definitions only first by order of appearance
236                        foreach ($styles[1] as $i => $type) {
237                                if ($type=="" && $styles[3][$i]=="") {
238                                        $styledefinition = trim($styles[5][$i]);
239                                        $styletag = preg_replace("/ *, */", "|", trim($styles[2][$i])); //echo $styletag."<br />";
240                                        $styleclass = "";
241                                        // process TAG {...} and TAG1, TAG2 {...} but not TAG1 TAG2 {...} or #divname styles
242                                        if (!preg_match("/ /", $styletag) && !preg_match("/#/", $styletag)) {
243                                                $pattern = "!<(".$styletag.")([^>]*(?= /)|[^>]*)( /)?>!mi";
244                                                $this->Body = preg_replace_callback ($pattern, 'facteur_addstyle' , $this->Body);
245                                                $styles[6][$i]=1; // mark as injected inline
246                                        }
247                                }
248                        }
249
250                        // append additional .CLASS {...} and TAG.CLASS {...} styling by order of appearance
251                        // important to do so after TAG {...} definitions, so that class attributes override TAG styles when needed
252                        foreach ($styles[1] as $i => $type) {
253                                if ($type!="." && $styles[3][$i]=="." ) {       // class definition for a specific tag
254                                        $styledefinition = trim($styles[5][$i]);
255                                        $styletag = trim($styles[2][$i]);
256                                        $styleclass = trim($styles[4][$i]);
257                                        $pattern = "!<(".$styletag.")([^>]* class\=['\"][^'\"]*".$styleclass."[^'\"]*['\"][^>]*(?= /)|[^>]* class\=['\"][^'\"]*".$styleclass."[^'\"]*['\"][^>]*)( />)?>!mi";
258                                        $this->Body = preg_replace_callback ($pattern, 'facteur_addstyle' , $this->Body);
259                                        $styles[6][$i]=1; // mark as injected inline
260
261                                } elseif ($type=="." && $styles[3][$i]=="" ) {  // general class definition for any tag
262                                        $styledefinition = trim($styles[5][$i]);
263                                        $styletag = "";
264                                        $styleclass = trim($styles[2][$i]);
265                                        $pattern = "!<(\w+)([^>]* class\=['\"]".$styleclass."['\"][^>]*(?= /)|[^>]* class\=['\"]".$styleclass."['\"][^>]*)( />)?>!mi";
266                                        $this->Body = preg_replace_callback ($pattern, 'facteur_addstyle' , $this->Body);
267                                        $styles[6][$i]=1; // mark as injected inline
268                                }
269                        }
270
271
272                        /* move all style declarations that weren't injected from <head> to a <body> <style> section,
273                           including but not limited to:
274                           - pseudo-classes like a:hover {...} as they can't be set inline
275                           - declaration chains like UL LI {...}
276                           - #divname {...}. These are not supported by email clients like Mac/Entourage anyway, it seems. */
277                        foreach ($styles[1] as $i => $type) {
278                                if ($styles[6][$i]=="") {
279                                        // add a <style type="text/css"> section after <body> if there's isn't one yet
280                                        if (preg_match ("!<body[^>]*>\s*<style!mi", $this->Body)==0) {
281                                                $this->Body = preg_replace ("/(<body[^>]*>)/i", "\n\$1\n".'<style type="text/css">'."\n<!--\n-->\n</style>\n", $this->Body);
282                                        }
283                                        // append a copy of the pseudo-element declaration to that body style section
284                                        $styledefinition = trim($styles[5][$i]);
285                                        $styledefinition = preg_replace ("!\s+!mi", " ", $styledefinition ); // convert style definition to a one-liner (optional)
286                                        $declaration = $styles[1][$i].trim($styles[2][$i]).$styles[3][$i].trim($styles[4][$i])." { ".$styledefinition." }";
287                                        $this->Body = preg_replace ("!(<body[^>]*>\s*<style[^>]*>\s*<\!\-\-[^>]*)"."(\s*\-\->\s*</style>)!si", "\$1".$declaration."\n\$2", $this->Body);
288                                        $styles[6][$i]= 2; // mark as moved to <style> section in <body>
289                                }
290                        }
291
292                        // remove stylesheet declaration(s) from <head> section (comment following line out if not wanted)
293                        //$this->Body = preg_replace ("!(<head>.*)<style type.*</style>(.*</head>)!si", "\$1\$2" , $this->Body);
294
295                        // check what styles have been injected
296#                       print_r($styles);
297       
298                }
299
300
301                function ConvertirUtf8VersIso8859() {
302                        $this->Body             = str_replace('’',"'",$this->Body);
303                        $this->AltBody  = str_replace('’',"'",$this->AltBody);
304                        $this->CharSet  = 'iso-8859-1';
305                        $this->Body             = str_replace('charset=utf-8', 'charset=iso-8859-1', $this->Body);
306                        $this->Body             = utf8_decode($this->Body);
307                        $this->AltBody  = utf8_decode($this->AltBody);
308                        $this->Subject  = utf8_decode($this->Subject);
309                        $this->FromName = utf8_decode($this->FromName);
310                }
311
312                function ConvertirAccents() {
313                        // tableau à compléter au fur et à mesure
314                        $cor = array(
315                                                        'à' => '&agrave;',
316                                                        'â' => '&acirc;',
317                                                        'ä' => '&auml;',
318                                                        'ç' => '&ccedil;',
319                                                        'é' => '&eacute;',
320                                                        'è' => '&egrave;',
321                                                        'ê' => '&ecirc;',
322                                                        'ë' => '&euml;',
323                                                        'î' => '&icirc;',
324                                                        'ï' => '&iuml;',
325                                                        'ò' => '&ograve;',
326                                                        'ô' => '&ocirc;',
327                                                        'ö' => '&ouml;',
328                                                        'ù' => '&ugrave;',
329                                                        'û' => '&ucirc;',
330                                                        'œ' => '&oelig;',
331                                                        '€' => '&euro;'
332                                                );
333
334                        $this->Body = strtr($this->Body, $cor);
335                }
336
337        }
338
339?>
Note: See TracBrowser for help on using the repository browser.