web/lib/Zend/Mime.php
changeset 1230 68c69c656a2c
parent 807 877f952ae2bd
equal deleted inserted replaced
1229:5a6b6e770365 1230:68c69c656a2c
    12  * obtain it through the world-wide-web, please send an email
    12  * obtain it through the world-wide-web, please send an email
    13  * to license@zend.com so we can send you a copy immediately.
    13  * to license@zend.com so we can send you a copy immediately.
    14  *
    14  *
    15  * @category   Zend
    15  * @category   Zend
    16  * @package    Zend_Mime
    16  * @package    Zend_Mime
    17  * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
    17  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
    18  * @license    http://framework.zend.com/license/new-bsd     New BSD License
    18  * @license    http://framework.zend.com/license/new-bsd     New BSD License
    19  * @version    $Id: Mime.php 24953 2012-06-13 19:09:58Z rob $
    19  * @version    $Id$
    20  */
    20  */
    21 
       
    22 
    21 
    23 /**
    22 /**
    24  * Support class for MultiPart Mime Messages
    23  * Support class for MultiPart Mime Messages
    25  *
    24  *
    26  * @category   Zend
    25  * @category   Zend
    27  * @package    Zend_Mime
    26  * @package    Zend_Mime
    28  * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
    27  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
    29  * @license    http://framework.zend.com/license/new-bsd     New BSD License
    28  * @license    http://framework.zend.com/license/new-bsd     New BSD License
    30  */
    29  */
    31 class Zend_Mime
    30 class Zend_Mime
    32 {
    31 {
    33     const TYPE_OCTETSTREAM = 'application/octet-stream';
    32     const TYPE_OCTETSTREAM         = 'application/octet-stream';
    34     const TYPE_TEXT = 'text/plain';
    33     const TYPE_TEXT                = 'text/plain';
    35     const TYPE_HTML = 'text/html';
    34     const TYPE_HTML                = 'text/html';
    36     const ENCODING_7BIT = '7bit';
    35     const ENCODING_7BIT            = '7bit';
    37     const ENCODING_8BIT = '8bit';
    36     const ENCODING_8BIT            = '8bit';
    38     const ENCODING_QUOTEDPRINTABLE = 'quoted-printable';
    37     const ENCODING_QUOTEDPRINTABLE = 'quoted-printable';
    39     const ENCODING_BASE64 = 'base64';
    38     const ENCODING_BASE64          = 'base64';
    40     const DISPOSITION_ATTACHMENT = 'attachment';
    39     const DISPOSITION_ATTACHMENT   = 'attachment';
    41     const DISPOSITION_INLINE = 'inline';
    40     const DISPOSITION_INLINE       = 'inline';
    42     const LINELENGTH = 72;
    41     const LINELENGTH               = 72;
    43     const LINEEND = "\n";
    42     const LINEEND                  = "\n";
    44     const MULTIPART_ALTERNATIVE = 'multipart/alternative';
    43     const MULTIPART_ALTERNATIVE    = 'multipart/alternative';
    45     const MULTIPART_MIXED = 'multipart/mixed';
    44     const MULTIPART_MIXED          = 'multipart/mixed';
    46     const MULTIPART_RELATED = 'multipart/related';
    45     const MULTIPART_RELATED        = 'multipart/related';
    47 
    46 
       
    47     /**
       
    48      * Boundary
       
    49      *
       
    50      * @var null|string
       
    51      */
    48     protected $_boundary;
    52     protected $_boundary;
       
    53 
       
    54     /**
       
    55      * @var int
       
    56      */
    49     protected static $makeUnique = 0;
    57     protected static $makeUnique = 0;
    50 
    58 
    51     // lookup-Tables for QuotedPrintable
    59     /**
       
    60      * Lookup-Tables for QuotedPrintable
       
    61      *
       
    62      * @var array
       
    63      */
    52     public static $qpKeys = array(
    64     public static $qpKeys = array(
    53         "\x00","\x01","\x02","\x03","\x04","\x05","\x06","\x07",
    65         "\x00",
    54         "\x08","\x09","\x0A","\x0B","\x0C","\x0D","\x0E","\x0F",
    66         "\x01",
    55         "\x10","\x11","\x12","\x13","\x14","\x15","\x16","\x17",
    67         "\x02",
    56         "\x18","\x19","\x1A","\x1B","\x1C","\x1D","\x1E","\x1F",
    68         "\x03",
    57         "\x7F","\x80","\x81","\x82","\x83","\x84","\x85","\x86",
    69         "\x04",
    58         "\x87","\x88","\x89","\x8A","\x8B","\x8C","\x8D","\x8E",
    70         "\x05",
    59         "\x8F","\x90","\x91","\x92","\x93","\x94","\x95","\x96",
    71         "\x06",
    60         "\x97","\x98","\x99","\x9A","\x9B","\x9C","\x9D","\x9E",
    72         "\x07",
    61         "\x9F","\xA0","\xA1","\xA2","\xA3","\xA4","\xA5","\xA6",
    73         "\x08",
    62         "\xA7","\xA8","\xA9","\xAA","\xAB","\xAC","\xAD","\xAE",
    74         "\x09",
    63         "\xAF","\xB0","\xB1","\xB2","\xB3","\xB4","\xB5","\xB6",
    75         "\x0A",
    64         "\xB7","\xB8","\xB9","\xBA","\xBB","\xBC","\xBD","\xBE",
    76         "\x0B",
    65         "\xBF","\xC0","\xC1","\xC2","\xC3","\xC4","\xC5","\xC6",
    77         "\x0C",
    66         "\xC7","\xC8","\xC9","\xCA","\xCB","\xCC","\xCD","\xCE",
    78         "\x0D",
    67         "\xCF","\xD0","\xD1","\xD2","\xD3","\xD4","\xD5","\xD6",
    79         "\x0E",
    68         "\xD7","\xD8","\xD9","\xDA","\xDB","\xDC","\xDD","\xDE",
    80         "\x0F",
    69         "\xDF","\xE0","\xE1","\xE2","\xE3","\xE4","\xE5","\xE6",
    81         "\x10",
    70         "\xE7","\xE8","\xE9","\xEA","\xEB","\xEC","\xED","\xEE",
    82         "\x11",
    71         "\xEF","\xF0","\xF1","\xF2","\xF3","\xF4","\xF5","\xF6",
    83         "\x12",
    72         "\xF7","\xF8","\xF9","\xFA","\xFB","\xFC","\xFD","\xFE",
    84         "\x13",
       
    85         "\x14",
       
    86         "\x15",
       
    87         "\x16",
       
    88         "\x17",
       
    89         "\x18",
       
    90         "\x19",
       
    91         "\x1A",
       
    92         "\x1B",
       
    93         "\x1C",
       
    94         "\x1D",
       
    95         "\x1E",
       
    96         "\x1F",
       
    97         "\x7F",
       
    98         "\x80",
       
    99         "\x81",
       
   100         "\x82",
       
   101         "\x83",
       
   102         "\x84",
       
   103         "\x85",
       
   104         "\x86",
       
   105         "\x87",
       
   106         "\x88",
       
   107         "\x89",
       
   108         "\x8A",
       
   109         "\x8B",
       
   110         "\x8C",
       
   111         "\x8D",
       
   112         "\x8E",
       
   113         "\x8F",
       
   114         "\x90",
       
   115         "\x91",
       
   116         "\x92",
       
   117         "\x93",
       
   118         "\x94",
       
   119         "\x95",
       
   120         "\x96",
       
   121         "\x97",
       
   122         "\x98",
       
   123         "\x99",
       
   124         "\x9A",
       
   125         "\x9B",
       
   126         "\x9C",
       
   127         "\x9D",
       
   128         "\x9E",
       
   129         "\x9F",
       
   130         "\xA0",
       
   131         "\xA1",
       
   132         "\xA2",
       
   133         "\xA3",
       
   134         "\xA4",
       
   135         "\xA5",
       
   136         "\xA6",
       
   137         "\xA7",
       
   138         "\xA8",
       
   139         "\xA9",
       
   140         "\xAA",
       
   141         "\xAB",
       
   142         "\xAC",
       
   143         "\xAD",
       
   144         "\xAE",
       
   145         "\xAF",
       
   146         "\xB0",
       
   147         "\xB1",
       
   148         "\xB2",
       
   149         "\xB3",
       
   150         "\xB4",
       
   151         "\xB5",
       
   152         "\xB6",
       
   153         "\xB7",
       
   154         "\xB8",
       
   155         "\xB9",
       
   156         "\xBA",
       
   157         "\xBB",
       
   158         "\xBC",
       
   159         "\xBD",
       
   160         "\xBE",
       
   161         "\xBF",
       
   162         "\xC0",
       
   163         "\xC1",
       
   164         "\xC2",
       
   165         "\xC3",
       
   166         "\xC4",
       
   167         "\xC5",
       
   168         "\xC6",
       
   169         "\xC7",
       
   170         "\xC8",
       
   171         "\xC9",
       
   172         "\xCA",
       
   173         "\xCB",
       
   174         "\xCC",
       
   175         "\xCD",
       
   176         "\xCE",
       
   177         "\xCF",
       
   178         "\xD0",
       
   179         "\xD1",
       
   180         "\xD2",
       
   181         "\xD3",
       
   182         "\xD4",
       
   183         "\xD5",
       
   184         "\xD6",
       
   185         "\xD7",
       
   186         "\xD8",
       
   187         "\xD9",
       
   188         "\xDA",
       
   189         "\xDB",
       
   190         "\xDC",
       
   191         "\xDD",
       
   192         "\xDE",
       
   193         "\xDF",
       
   194         "\xE0",
       
   195         "\xE1",
       
   196         "\xE2",
       
   197         "\xE3",
       
   198         "\xE4",
       
   199         "\xE5",
       
   200         "\xE6",
       
   201         "\xE7",
       
   202         "\xE8",
       
   203         "\xE9",
       
   204         "\xEA",
       
   205         "\xEB",
       
   206         "\xEC",
       
   207         "\xED",
       
   208         "\xEE",
       
   209         "\xEF",
       
   210         "\xF0",
       
   211         "\xF1",
       
   212         "\xF2",
       
   213         "\xF3",
       
   214         "\xF4",
       
   215         "\xF5",
       
   216         "\xF6",
       
   217         "\xF7",
       
   218         "\xF8",
       
   219         "\xF9",
       
   220         "\xFA",
       
   221         "\xFB",
       
   222         "\xFC",
       
   223         "\xFD",
       
   224         "\xFE",
    73         "\xFF"
   225         "\xFF"
    74         );
   226     );
    75 
   227 
       
   228     /**
       
   229      * @var array
       
   230      */
    76     public static $qpReplaceValues = array(
   231     public static $qpReplaceValues = array(
    77         "=00","=01","=02","=03","=04","=05","=06","=07",
   232         "=00",
    78         "=08","=09","=0A","=0B","=0C","=0D","=0E","=0F",
   233         "=01",
    79         "=10","=11","=12","=13","=14","=15","=16","=17",
   234         "=02",
    80         "=18","=19","=1A","=1B","=1C","=1D","=1E","=1F",
   235         "=03",
    81         "=7F","=80","=81","=82","=83","=84","=85","=86",
   236         "=04",
    82         "=87","=88","=89","=8A","=8B","=8C","=8D","=8E",
   237         "=05",
    83         "=8F","=90","=91","=92","=93","=94","=95","=96",
   238         "=06",
    84         "=97","=98","=99","=9A","=9B","=9C","=9D","=9E",
   239         "=07",
    85         "=9F","=A0","=A1","=A2","=A3","=A4","=A5","=A6",
   240         "=08",
    86         "=A7","=A8","=A9","=AA","=AB","=AC","=AD","=AE",
   241         "=09",
    87         "=AF","=B0","=B1","=B2","=B3","=B4","=B5","=B6",
   242         "=0A",
    88         "=B7","=B8","=B9","=BA","=BB","=BC","=BD","=BE",
   243         "=0B",
    89         "=BF","=C0","=C1","=C2","=C3","=C4","=C5","=C6",
   244         "=0C",
    90         "=C7","=C8","=C9","=CA","=CB","=CC","=CD","=CE",
   245         "=0D",
    91         "=CF","=D0","=D1","=D2","=D3","=D4","=D5","=D6",
   246         "=0E",
    92         "=D7","=D8","=D9","=DA","=DB","=DC","=DD","=DE",
   247         "=0F",
    93         "=DF","=E0","=E1","=E2","=E3","=E4","=E5","=E6",
   248         "=10",
    94         "=E7","=E8","=E9","=EA","=EB","=EC","=ED","=EE",
   249         "=11",
    95         "=EF","=F0","=F1","=F2","=F3","=F4","=F5","=F6",
   250         "=12",
    96         "=F7","=F8","=F9","=FA","=FB","=FC","=FD","=FE",
   251         "=13",
       
   252         "=14",
       
   253         "=15",
       
   254         "=16",
       
   255         "=17",
       
   256         "=18",
       
   257         "=19",
       
   258         "=1A",
       
   259         "=1B",
       
   260         "=1C",
       
   261         "=1D",
       
   262         "=1E",
       
   263         "=1F",
       
   264         "=7F",
       
   265         "=80",
       
   266         "=81",
       
   267         "=82",
       
   268         "=83",
       
   269         "=84",
       
   270         "=85",
       
   271         "=86",
       
   272         "=87",
       
   273         "=88",
       
   274         "=89",
       
   275         "=8A",
       
   276         "=8B",
       
   277         "=8C",
       
   278         "=8D",
       
   279         "=8E",
       
   280         "=8F",
       
   281         "=90",
       
   282         "=91",
       
   283         "=92",
       
   284         "=93",
       
   285         "=94",
       
   286         "=95",
       
   287         "=96",
       
   288         "=97",
       
   289         "=98",
       
   290         "=99",
       
   291         "=9A",
       
   292         "=9B",
       
   293         "=9C",
       
   294         "=9D",
       
   295         "=9E",
       
   296         "=9F",
       
   297         "=A0",
       
   298         "=A1",
       
   299         "=A2",
       
   300         "=A3",
       
   301         "=A4",
       
   302         "=A5",
       
   303         "=A6",
       
   304         "=A7",
       
   305         "=A8",
       
   306         "=A9",
       
   307         "=AA",
       
   308         "=AB",
       
   309         "=AC",
       
   310         "=AD",
       
   311         "=AE",
       
   312         "=AF",
       
   313         "=B0",
       
   314         "=B1",
       
   315         "=B2",
       
   316         "=B3",
       
   317         "=B4",
       
   318         "=B5",
       
   319         "=B6",
       
   320         "=B7",
       
   321         "=B8",
       
   322         "=B9",
       
   323         "=BA",
       
   324         "=BB",
       
   325         "=BC",
       
   326         "=BD",
       
   327         "=BE",
       
   328         "=BF",
       
   329         "=C0",
       
   330         "=C1",
       
   331         "=C2",
       
   332         "=C3",
       
   333         "=C4",
       
   334         "=C5",
       
   335         "=C6",
       
   336         "=C7",
       
   337         "=C8",
       
   338         "=C9",
       
   339         "=CA",
       
   340         "=CB",
       
   341         "=CC",
       
   342         "=CD",
       
   343         "=CE",
       
   344         "=CF",
       
   345         "=D0",
       
   346         "=D1",
       
   347         "=D2",
       
   348         "=D3",
       
   349         "=D4",
       
   350         "=D5",
       
   351         "=D6",
       
   352         "=D7",
       
   353         "=D8",
       
   354         "=D9",
       
   355         "=DA",
       
   356         "=DB",
       
   357         "=DC",
       
   358         "=DD",
       
   359         "=DE",
       
   360         "=DF",
       
   361         "=E0",
       
   362         "=E1",
       
   363         "=E2",
       
   364         "=E3",
       
   365         "=E4",
       
   366         "=E5",
       
   367         "=E6",
       
   368         "=E7",
       
   369         "=E8",
       
   370         "=E9",
       
   371         "=EA",
       
   372         "=EB",
       
   373         "=EC",
       
   374         "=ED",
       
   375         "=EE",
       
   376         "=EF",
       
   377         "=F0",
       
   378         "=F1",
       
   379         "=F2",
       
   380         "=F3",
       
   381         "=F4",
       
   382         "=F5",
       
   383         "=F6",
       
   384         "=F7",
       
   385         "=F8",
       
   386         "=F9",
       
   387         "=FA",
       
   388         "=FB",
       
   389         "=FC",
       
   390         "=FD",
       
   391         "=FE",
    97         "=FF"
   392         "=FF"
    98         );
   393     );
    99 
   394 
       
   395     /**
       
   396      * @var string
       
   397      */
   100     public static $qpKeysString =
   398     public static $qpKeysString =
   101          "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF";
   399         "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF";
   102 
   400 
   103     /**
   401     /**
   104      * Check if the given string is "printable"
   402      * Check if the given string is "printable"
   105      *
   403      *
   106      * Checks that a string contains no unprintable characters. If this returns
   404      * Checks that a string contains no unprintable characters. If this returns
   115     }
   413     }
   116 
   414 
   117     /**
   415     /**
   118      * Encode a given string with the QUOTED_PRINTABLE mechanism and wrap the lines.
   416      * Encode a given string with the QUOTED_PRINTABLE mechanism and wrap the lines.
   119      *
   417      *
   120      * @param string $str
   418      * @param  string $str
   121      * @param int $lineLength Defaults to {@link LINELENGTH}
   419      * @param  int    $lineLength Line length; defaults to {@link LINELENGTH}
   122      * @param int $lineEnd Defaults to {@link LINEEND}
   420      * @param  string $lineEnd    Line end; defaults to {@link LINEEND}
   123      * @return string
   421      * @return string
   124      */
   422      */
   125     public static function encodeQuotedPrintable($str,
   423     public static function encodeQuotedPrintable(
       
   424         $str,
   126         $lineLength = self::LINELENGTH,
   425         $lineLength = self::LINELENGTH,
   127         $lineEnd = self::LINEEND)
   426         $lineEnd = self::LINEEND
       
   427     )
   128     {
   428     {
   129         $out = '';
   429         $out = '';
   130         $str = self::_encodeQuotedPrintable($str);
   430         $str = self::_encodeQuotedPrintable($str);
   131 
   431 
   132         // Split encoded text into separate lines
   432         // Split encoded text into separate lines
   133         while(strlen($str) > 0) {
   433         while (strlen($str) > 0) {
   134             $ptr = strlen($str);
   434             $ptr = strlen($str);
   135             if ($ptr > $lineLength) {
   435             if ($ptr > $lineLength) {
   136                 $ptr = $lineLength;
   436                 $ptr = $lineLength;
   137             }
   437             }
   138 
   438 
   152             $str = substr($str, $ptr);
   452             $str = substr($str, $ptr);
   153         }
   453         }
   154 
   454 
   155         $out = rtrim($out, $lineEnd);
   455         $out = rtrim($out, $lineEnd);
   156         $out = rtrim($out, '=');
   456         $out = rtrim($out, '=');
       
   457 
   157         return $out;
   458         return $out;
   158     }
   459     }
   159 
   460 
   160     /**
   461     /**
   161      * Converts a string into quoted printable format.
   462      * Converts a string into quoted printable format.
   166     private static function _encodeQuotedPrintable($str)
   467     private static function _encodeQuotedPrintable($str)
   167     {
   468     {
   168         $str = str_replace('=', '=3D', $str);
   469         $str = str_replace('=', '=3D', $str);
   169         $str = str_replace(self::$qpKeys, self::$qpReplaceValues, $str);
   470         $str = str_replace(self::$qpKeys, self::$qpReplaceValues, $str);
   170         $str = rtrim($str);
   471         $str = rtrim($str);
       
   472 
   171         return $str;
   473         return $str;
   172     }
   474     }
   173 
   475 
   174     /**
   476     /**
   175      * Encode a given string with the QUOTED_PRINTABLE mechanism for Mail Headers.
   477      * Encode a given string with the QUOTED_PRINTABLE mechanism for Mail Headers.
   176      *
   478      *
   177      * Mail headers depend on an extended quoted printable algorithm otherwise
   479      * Mail headers depend on an extended quoted printable algorithm otherwise
   178      * a range of bugs can occur.
   480      * a range of bugs can occur.
   179      *
   481      *
   180      * @param string $str
   482      * @param  string $str
   181      * @param string $charset
   483      * @param  string $charset
   182      * @param int $lineLength Defaults to {@link LINELENGTH}
   484      * @param  int    $lineLength Line length; defaults to {@link LINELENGTH}
   183      * @param int $lineEnd Defaults to {@link LINEEND}
   485      * @param  string $lineEnd    Line end; defaults to {@link LINEEND}
   184      * @return string
   486      * @return string
   185      */
   487      */
   186     public static function encodeQuotedPrintableHeader($str, $charset,
   488     public static function encodeQuotedPrintableHeader(
   187         $lineLength = self::LINELENGTH,
   489         $str, $charset, $lineLength = self::LINELENGTH, $lineEnd = self::LINEEND
   188         $lineEnd = self::LINEEND)
   490     )
   189     {
   491     {
   190         // Reduce line-length by the length of the required delimiter, charsets and encoding
   492         // Reduce line-length by the length of the required delimiter, charsets and encoding
   191         $prefix = sprintf('=?%s?Q?', $charset);
   493         $prefix     = sprintf('=?%s?Q?', $charset);
   192         $lineLength = $lineLength-strlen($prefix)-3;
   494         $lineLength = $lineLength - strlen($prefix) - 3;
   193 
   495 
   194         $str = self::_encodeQuotedPrintable($str);
   496         $str = self::_encodeQuotedPrintable($str);
   195 
   497 
   196         // Mail-Header required chars have to be encoded also:
   498         // Mail-Header required chars have to be encoded also:
   197         $str = str_replace(array('?', ' ', '_', ','), array('=3F', '=20', '=5F', '=2C'), $str);
   499         $str = str_replace(
       
   500             array('?', ' ', '_', ','), array('=3F', '=20', '=5F', '=2C'), $str
       
   501         );
   198 
   502 
   199         // initialize first line, we need it anyways
   503         // initialize first line, we need it anyways
   200         $lines = array(0 => "");
   504         $lines = array(0 => "");
   201 
   505 
   202         // Split encoded text into separate lines
   506         // Split encoded text into separate lines
   203         $tmp = "";
   507         $tmp = "";
   204         while(strlen($str) > 0) {
   508         while (strlen($str) > 0) {
   205             $currentLine = max(count($lines)-1, 0);
   509             $currentLine = max(count($lines) - 1, 0);
   206             $token       = self::getNextQuotedPrintableToken($str);
   510             $token       = self::getNextQuotedPrintableToken($str);
   207             $str         = substr($str, strlen($token));
   511             $str         = substr($str, strlen($token));
   208 
   512 
   209             $tmp .= $token;
   513             $tmp .= $token;
   210             if($token == '=20') {
   514             if ($token == '=20') {
   211                 // only if we have a single char token or space, we can append the
   515                 // only if we have a single char token or space, we can append the
   212                 // tempstring it to the current line or start a new line if necessary.
   516                 // tempstring it to the current line or start a new line if necessary.
   213                 if(strlen($lines[$currentLine].$tmp) > $lineLength) {
   517                 if (strlen($lines[$currentLine] . $tmp) > $lineLength) {
   214                     $lines[$currentLine+1] = $tmp;
   518                     $lines[$currentLine + 1] = $tmp;
   215                 } else {
   519                 } else {
   216                     $lines[$currentLine] .= $tmp;
   520                     $lines[$currentLine] .= $tmp;
   217                 }
   521                 }
   218                 $tmp = "";
   522                 $tmp = "";
   219             }
   523             }
   220             // don't forget to append the rest to the last line
   524             // don't forget to append the rest to the last line
   221             if(strlen($str) == 0) {
   525             if (strlen($str) == 0) {
   222                 $lines[$currentLine] .= $tmp;
   526                 $lines[$currentLine] .= $tmp;
   223             }
   527             }
   224         }
   528         }
   225 
   529 
   226         // assemble the lines together by pre- and appending delimiters, charset, encoding.
   530         // assemble the lines together by pre- and appending delimiters, charset, encoding.
   227         for($i = 0; $i < count($lines); $i++) {
   531         for ($i = 0; $i < count($lines); $i++) {
   228             $lines[$i] = " ".$prefix.$lines[$i]."?=";
   532             $lines[$i] = " " . $prefix . $lines[$i] . "?=";
   229         }
   533         }
   230         $str = trim(implode($lineEnd, $lines));
   534         $str = trim(implode($lineEnd, $lines));
       
   535 
   231         return $str;
   536         return $str;
   232     }
   537     }
   233 
   538 
   234     /**
   539     /**
   235      * Retrieves the first token from a quoted printable string.
   540      * Retrieves the first token from a quoted printable string.
   237      * @param  string $str
   542      * @param  string $str
   238      * @return string
   543      * @return string
   239      */
   544      */
   240     private static function getNextQuotedPrintableToken($str)
   545     private static function getNextQuotedPrintableToken($str)
   241     {
   546     {
   242         if(substr($str, 0, 1) == "=") {
   547         if (substr($str, 0, 1) == "=") {
   243             $token = substr($str, 0, 3);
   548             $token = substr($str, 0, 3);
   244         } else {
   549         } else {
   245             $token = substr($str, 0, 1);
   550             $token = substr($str, 0, 1);
   246         }
   551         }
       
   552 
   247         return $token;
   553         return $token;
   248     }
   554     }
   249 
   555 
   250     /**
   556     /**
   251      * Encode a given string in mail header compatible base64 encoding.
   557      * Encode a given string in mail header compatible base64 encoding.
   252      *
   558      *
   253      * @param string $str
   559      * @param  string $str
   254      * @param string $charset
   560      * @param  string $charset
   255      * @param int $lineLength Defaults to {@link LINELENGTH}
   561      * @param  int    $lineLength Line length; defaults to {@link LINELENGTH}
   256      * @param int $lineEnd Defaults to {@link LINEEND}
   562      * @param  string $lineEnd    Line end; defaults to {@link LINEEND}
   257      * @return string
   563      * @return string
   258      */
   564      */
   259     public static function encodeBase64Header($str,
   565     public static function encodeBase64Header(
   260         $charset,
   566         $str, $charset, $lineLength = self::LINELENGTH, $lineEnd = self::LINEEND
   261         $lineLength = self::LINELENGTH,
   567     )
   262         $lineEnd = self::LINEEND)
   568     {
   263     {
   569         $prefix          = '=?' . $charset . '?B?';
   264         $prefix = '=?' . $charset . '?B?';
   570         $suffix          = '?=';
   265         $suffix = '?=';
       
   266         $remainingLength = $lineLength - strlen($prefix) - strlen($suffix);
   571         $remainingLength = $lineLength - strlen($prefix) - strlen($suffix);
   267 
   572 
   268         $encodedValue = self::encodeBase64($str, $remainingLength, $lineEnd);
   573         $encodedValue = self::encodeBase64($str, $remainingLength, $lineEnd);
   269         $encodedValue = str_replace($lineEnd, $suffix . $lineEnd . ' ' . $prefix, $encodedValue);
   574         $encodedValue = str_replace(
       
   575             $lineEnd, $suffix . $lineEnd . ' ' . $prefix, $encodedValue
       
   576         );
   270         $encodedValue = $prefix . $encodedValue . $suffix;
   577         $encodedValue = $prefix . $encodedValue . $suffix;
       
   578 
   271         return $encodedValue;
   579         return $encodedValue;
   272     }
   580     }
   273 
   581 
   274     /**
   582     /**
   275      * Encode a given string in base64 encoding and break lines
   583      * Encode a given string in base64 encoding and break lines
   276      * according to the maximum linelength.
   584      * according to the maximum linelength.
   277      *
   585      *
   278      * @param string $str
   586      * @param  string $str
   279      * @param int $lineLength Defaults to {@link LINELENGTH}
   587      * @param  int    $lineLength Line length; defaults to {@link LINELENGTH}
   280      * @param int $lineEnd Defaults to {@link LINEEND}
   588      * @param  string $lineEnd    Line end; defaults to {@link LINEEND}
   281      * @return string
   589      * @return string
   282      */
   590      */
   283     public static function encodeBase64($str,
   591     public static function encodeBase64(
   284         $lineLength = self::LINELENGTH,
   592         $str, $lineLength = self::LINELENGTH, $lineEnd = self::LINEEND
   285         $lineEnd = self::LINEEND)
   593     )
   286     {
   594     {
   287         return rtrim(chunk_split(base64_encode($str), $lineLength, $lineEnd));
   595         return rtrim(chunk_split(base64_encode($str), $lineLength, $lineEnd));
   288     }
   596     }
   289 
   597 
   290     /**
   598     /**
   291      * Constructor
   599      * Constructor
   292      *
   600      *
   293      * @param null|string $boundary
   601      * @param null|string $boundary
   294      * @access public
       
   295      * @return void
       
   296      */
   602      */
   297     public function __construct($boundary = null)
   603     public function __construct($boundary = null)
   298     {
   604     {
   299         // This string needs to be somewhat unique
   605         // This string needs to be somewhat unique
   300         if ($boundary === null) {
   606         if ($boundary === null) {
   307     /**
   613     /**
   308      * Encode the given string with the given encoding.
   614      * Encode the given string with the given encoding.
   309      *
   615      *
   310      * @param string $str
   616      * @param string $str
   311      * @param string $encoding
   617      * @param string $encoding
   312      * @param string $EOL EOL string; defaults to {@link Zend_Mime::LINEEND}
   618      * @param string $EOL Line end; defaults to {@link Zend_Mime::LINEEND}
   313      * @return string
   619      * @return string
   314      */
   620      */
   315     public static function encode($str, $encoding, $EOL = self::LINEEND)
   621     public static function encode($str, $encoding, $EOL = self::LINEEND)
   316     {
   622     {
   317         switch ($encoding) {
   623         switch ($encoding) {
   341     }
   647     }
   342 
   648 
   343     /**
   649     /**
   344      * Return a MIME boundary line
   650      * Return a MIME boundary line
   345      *
   651      *
   346      * @param mixed $EOL Defaults to {@link LINEEND}
   652      * @param  string $EOL Line end; defaults to {@link LINEEND}
   347      * @access public
       
   348      * @return string
   653      * @return string
   349      */
   654      */
   350     public function boundaryLine($EOL = self::LINEEND)
   655     public function boundaryLine($EOL = self::LINEEND)
   351     {
   656     {
   352         return $EOL . '--' . $this->_boundary . $EOL;
   657         return $EOL . '--' . $this->_boundary . $EOL;
   353     }
   658     }
   354 
   659 
   355     /**
   660     /**
   356      * Return MIME ending
   661      * Return MIME ending
   357      *
   662      *
   358      * @access public
   663      * @param  string $EOL Line end; defaults to {@link LINEEND}
   359      * @return string
   664      * @return string
   360      */
   665      */
   361     public function mimeEnd($EOL = self::LINEEND)
   666     public function mimeEnd($EOL = self::LINEEND)
   362     {
   667     {
   363         return $EOL . '--' . $this->_boundary . '--' . $EOL;
   668         return $EOL . '--' . $this->_boundary . '--' . $EOL;