Example #1
0
    /**
     * Encodes a header value as per RFC2047
     *
     * @param string $value      The header data to encode
     * @param string $charset    Character set name
     * @param string $encoding   Encoding name (base64 or quoted-printable)
     * @param int    $prefix_len Prefix length. Default: 0
     * @param string $eol        End-of-line sequence. Default: "\r\n"
     *
     * @return string            Encoded header data
     * @access public
     * @since 1.6.1
     */
    function encodeHeaderValue($value, $charset, $encoding, $prefix_len=0, $eol="\r\n")
    {
        // #17311: Use multibyte aware method (requires mbstring extension)
        if ($result = Mail_mimePart::encodeMB($value, $charset, $encoding, $prefix_len, $eol)) {
            return $result;
        }

        // Generate the header using the specified params and dynamicly
        // determine the maximum length of such strings.
        // 75 is the value specified in the RFC.
        $encoding = $encoding == 'base64' ? 'B' : 'Q';
        $prefix = '=?' . $charset . '?' . $encoding .'?';
        $suffix = '?=';
        $maxLength = 75 - strlen($prefix . $suffix);
        $maxLength1stLine = $maxLength - $prefix_len;

        if ($encoding == 'B') {
            // Base64 encode the entire string
            $value = base64_encode($value);

            // We can cut base64 every 4 characters, so the real max
            // we can get must be rounded down.
            $maxLength = $maxLength - ($maxLength % 4);
            $maxLength1stLine = $maxLength1stLine - ($maxLength1stLine % 4);

            $cutpoint = $maxLength1stLine;
            $output = '';

            while ($value) {
                // Split translated string at every $maxLength
                $part = substr($value, 0, $cutpoint);
                $value = substr($value, $cutpoint);
                $cutpoint = $maxLength;
                // RFC 2047 specifies that any split header should
                // be seperated by a CRLF SPACE.
                if ($output) {
                    $output .= $eol . ' ';
                }
                $output .= $prefix . $part . $suffix;
            }
            $value = $output;
        } else {
            // quoted-printable encoding has been selected
            $value = Mail_mimePart::encodeQP($value);

            // This regexp will break QP-encoded text at every $maxLength
            // but will not break any encoded letters.
            $reg1st = "|(.{0,$maxLength1stLine}[^\=][^\=])|";
            $reg2nd = "|(.{0,$maxLength}[^\=][^\=])|";

            if (strlen($value) > $maxLength1stLine) {
                // Begin with the regexp for the first line.
                $reg = $reg1st;
                $output = '';
                while ($value) {
                    // Split translated string at every $maxLength
                    // But make sure not to break any translated chars.
                    $found = preg_match($reg, $value, $matches);

                    // After this first line, we need to use a different
                    // regexp for the first line.
                    $reg = $reg2nd;

                    // Save the found part and encapsulate it in the
                    // prefix & suffix. Then remove the part from the
                    // $value_out variable.
                    if ($found) {
                        $part = $matches[0];
                        $len = strlen($matches[0]);
                        $value = substr($value, $len);
                    } else {
                        $part = $value;
                        $value = '';
                    }

                    // RFC 2047 specifies that any split header should
                    // be seperated by a CRLF SPACE
                    if ($output) {
                        $output .= $eol . ' ';
                    }
                    $output .= $prefix . $part . $suffix;
                }
                $value = $output;
            } else {
                $value = $prefix . $value . $suffix;
            }
        }

        return $value;
    }
Example #2
0
    /**
     * Encodes a header value as per RFC2047
     *
     * @param string $value      The header data to encode
     * @param string $charset    Character set name
     * @param string $encoding   Encoding name (base64 or quoted-printable)
     * @param int    $prefix_len Prefix length. Default: 0
     * @param string $eol        End-of-line sequence. Default: "\r\n"
     *
     * @return string            Encoded header data
     * @access public
     * @since 1.6.1
     */
    function encodeHeaderValue($value, $charset, $encoding, $prefix_len=0, $eol="\r\n")
    {
        if ($encoding == 'base64') {
            // Base64 encode the entire string
            $value = base64_encode($value);

            // Generate the header using the specified params and dynamicly 
            // determine the maximum length of such strings.
            // 75 is the value specified in the RFC.
            $prefix = '=?' . $charset . '?B?';
            $suffix = '?=';
            $maxLength = 75 - strlen($prefix . $suffix) - 2;
            $maxLength1stLine = $maxLength - $prefix_len;

            // We can cut base4 every 4 characters, so the real max
            // we can get must be rounded down.
            $maxLength = $maxLength - ($maxLength % 4);
            $maxLength1stLine = $maxLength1stLine - ($maxLength1stLine % 4);

            $cutpoint = $maxLength1stLine;
            $value_out = $value;
            $output = '';
            while ($value_out) {
                // Split translated string at every $maxLength
                $part = substr($value_out, 0, $cutpoint);
                $value_out = substr($value_out, $cutpoint);
                $cutpoint = $maxLength;
                // RFC 2047 specifies that any split header should
                // be seperated by a CRLF SPACE. 
                if ($output) {
                    $output .= $eol . ' ';
                }
                $output .= $prefix . $part . $suffix;
            }
            $value = $output;
        } else {
            // quoted-printable encoding has been selected
            $value = Mail_mimePart::encodeQP($value);

            // Generate the header using the specified params and dynamicly 
            // determine the maximum length of such strings.
            // 75 is the value specified in the RFC.
            $prefix = '=?' . $charset . '?Q?';
            $suffix = '?=';
            $maxLength = 75 - strlen($prefix . $suffix) - 3;
            $maxLength1stLine = $maxLength - $prefix_len;
            $maxLength = $maxLength - 1;

            // This regexp will break QP-encoded text at every $maxLength
            // but will not break any encoded letters.
            $reg = "/(([\^\$\*\-\+\.\|\'\";\(\)\[\]\{\}\/\\\\<>,@`!#%&:_a-zA-Z0-9]|=3D|=5F|=3F|=C[\d\w]=.{2}|=D\d=.{2}|=E\d=.{2}=.{2})+)/";

            $value_out = $value;
            $realMax = $maxLength1stLine + strlen($prefix . $suffix);
            if (strlen($value_out) >= $realMax) {
                // Begin with the regexp length for the first line.
                $regLength = $maxLength1stLine;
                $output = '';
                while ($value_out) {
                    // Split translated string at every $maxLength
                    // But make sure not to break any translated chars.
                    $found = preg_match($reg, substr($value_out, 0, $regLength), $matches);

                    // After this first line, we need to use a different
                    // regexp length for the first line.
                    $regLength = $maxLength;

                    // Save the found part and encapsulate it in the
                    // prefix & suffix. Then remove the part from the
                    // $value_out variable.
                    if ($found) {
                        $part = $matches[0];
                        $len = strlen($matches[0]);
                        $value_out = substr($value_out, $len);
                    } else {
                        $part = $value_out;
                        $value_out = "";
                    }

                    // RFC 2047 specifies that any split header should 
                    // be seperated by a CRLF SPACE
                    if ($output) {
                        $output .= $eol . ' ';
                    }
                    $output .= $prefix . $part . $suffix;
                }
                $value_out = $output;
            } else {
                $value_out = $prefix . $value_out . $suffix;
            }
            $value = $value_out;
        }

        return $value;
    }