Generate a MIME multipart boundary
@param string $textToBound Text of the email where the boundary needs to be inserted
@return string
14032
protected function getBoundary( $textToBound ) {
		$boundary = md5( 'php-gpglib' . uniqid( mt_rand(), true ) );
		while ( strpos( $textToBound, $boundary ) !== false ) {
			$boundary .= '=_';
		}
		return $boundary;
	}
211069
private function constructHTML ($firstBoundary)
    {

        // Reset the message

        $message		= NULL;

        // Set boundaries

        $secondBoundary	= '=====' . md5 (uniqid (time ()));
        $thirdBoundary	= '=====' . md5 (uniqid (time ()));

        // Get HTML and Plain strings

        $html			= NULL;
        $plain			= NULL;

        foreach ($this->_html as $htmlBlock)
        {
            $html .= $htmlBlock;
        }

        if ($this->_plain)
        {

            foreach ($this->_plain as $plainBlock)
            {
                $plain .= $plainBlock;
            }

        }
        else
        {
            $plain	= strip_tags ($html);
        }

        // If there are images

        if ($this->_imagesSet)
        {

            // Replace images with CID in HTML message

            foreach ($this->_images as $image)
            {

                $html	= preg_replace ($image['name'], 'cid:' . $image['cid'], $html);

            }

            // Generate HTML Message

            $message	.= '--' . $firstBoundary . $this->_nl;
            $message	.= 'Content-Type: multipart/related;' . $this->_nl . chr (9);
            $message	.= 'boundary="' . $secondBoundary . '"' . str_repeat ($this->_nl, 3);

            $message	.= '--' . $secondBoundary . $this->_nl;
            $message	.= 'Content-Type: Multipart/alternative;' . $this->_nl . chr (9);
            $message	.= 'boundary="' . $thirdBoundary . '"' . str_repeat ($this->_nl, 3);

            $message	.= '--' . $thirdBoundary . $this->_nl;
            $message	.= 'Content-Type: text/plain; "charset=iso-8859-1"' . $this->_nl;
            $message	.= 'Content-Transfer-Encoding: 8bit' . str_repeat ($this->_nl, 2);
            $message	.= $plain . str_repeat ($this->_nl, 2);

            $message	.= '--' . $thirdBoundary . $this->_nl;
            $message	.= 'Content-Type: text/html; "charset=iso-8859-1"' . $this->_nl;
            $message	.= 'Content-Transfer-Encoding: 8bit' . str_repeat ($this->_nl, 2);
            $message	.= $html . str_repeat ($this->_nl, 2);
            $message	.= '--' . $thirdBoundary . '--' . str_repeat ($this->_nl, 2);

            // Add Images

            foreach ($this->_images as $image)
            {
                $message	.= $this->constructImage ($image, $secondBoundary);
            }

            // End HTML

            $message	.= '--' . $secondBoundary . '--' . str_repeat ($this->_nl, 2);

        }
        else
        {

            // Generate HTML Message

            if ($plain)
            {

                $message	.= '--' . $firstBoundary . $this->_nl;
                $message	.= 'Content-Type: text/plain; charset="iso-8859-1"' . $this->_nl;
                $message	.= 'Content-Transfer-Encoding: 8bit' . str_repeat ($this->_nl, 2);
                $message	.= $plain . str_repeat ($this->_nl, 2);

            }

            if ($html)
            {

                $message	.= '--' . $firstBoundary . $this->_nl;
                $message	.= 'Content-Type: text/html; "charset=iso-8859-1"' . $this->_nl;
                $message	.= 'Content-Transfer-Encoding: 8bit' . str_repeat ($this->_nl, 2);
                $message	.= $html . str_repeat ($this->_nl, 2);

            }

        }

        // Return message

        return $message;

    }
949076
public static function generate(string $text = '', ?int $maxLength = null): string
    {
        $text = StripTags::strip($text);
        $text = \strtolower(\iconv('UTF-8', 'ASCII//TRANSLIT', $text));
        $text = \preg_replace('/[^a-z0-9\-\ ]/', '', $text);
        $text = \preg_replace('/[\s\-]+/', '-', $text);
        if (\is_int($maxLength)) {
            $text = \substr($text, 0, $maxLength);
        }
        $text = \rtrim($text, '-');

        return '/'.$text;
    }
203833
public function assembleAttachmentBody()
    {
        $body = array();
        $body[] = "This is a multi-part message in MIME format.";
        $body[] = "--{$this->_uid}";
        $body[] = "Content-Type: text/html; charset=\"utf-8\"";
        $body[] = "Content-Transfer-Encoding: quoted-printable";
        $body[] = "";
        $body[] = quoted_printable_encode($this->_message);
        $body[] = "";
        $body[] = "--{$this->_uid}";

        foreach ($this->_attachments as $attachment) {
            $body[] = $this->getAttachmentMimeTemplate($attachment);
        }

        return implode(PHP_EOL, $body) . '--';
    }
761541
private function renderAttachments(&$content, $boundary)
    {
        foreach($this->attachments as $file => $name) {
            if (!is_readable($file)) {
                throw new MailException('File could not be read: ' . $file); // @codeCoverageIgnore
            }
            $data = chunk_split(base64_encode(file_get_contents($file)));
            $type = mime_content_type($file);
            $content .= "\r\n";
            $content .= "--$boundary\r\n";
            $content .= "Content-Type: $type;\r\n\tname=\"$name\"\r\n";
            $content .= "Content-Transfer-Encoding: base64\r\n";
            $content .= "Content-Description: \"$name\"\r\n";
            $content .= "Content-Disposition: attachment;\r\n\tfilename=\"$name\"\r\n";
            $content .= "\r\n";
            $content .= "$data";
        }
    }
543502
protected function GetBoundary($boundary, $charSet, $contentType, $encoding)
    {
        $result = '';
        if ($charSet == '') {
            $charSet = $this->CharSet;
        }
        if ($contentType == '') {
            $contentType = $this->ContentType;
        }
        if ($encoding == '') {
            $encoding = $this->Encoding;
        }
        $result .= $this->TextLine('--' . $boundary);
        $result .= sprintf("Content-Type: %s; charset=\"%s\"", $contentType, $charSet);
        $result .= $this->LE;
        $result .= $this->HeaderLine('Content-Transfer-Encoding', $encoding);
        $result .= $this->LE;

        return $result;
    }
1336569
protected function getHtmlAttachmentBody()
    {
        $html   = $this->getHtmlBody();

        $body = array();
        $body[] = 'Content-Type: multipart/mixed; boundary="'.$this->boundary[1].'"';
        $body[] = null;
        $body[] = '--'.$this->boundary[1];

        foreach ($html as $line) {
            $body[] = $line;
        }

        return $this->addAttachmentBody($body);
    }
1257636
public function getMimeBoundary()
    {
        if ($this->mimeBoundary === false) {
            $this->mimeBoundary = null;
            $contentType = $this->getContentType();
            if ($contentType !== null) {
                $this->mimeBoundary = $contentType->getValueFor('boundary');
            }
        }
        return $this->mimeBoundary;
    }
381998
public static function emailToLink($text)
    {
        preg_match_all("/([\\\a-z0-9_\-\.]+)@([a-z0-9-]{1,64})\.([a-z]{2,10})/iu", $text, $emails);

        foreach ($emails[0] as $email) {
            $email = trim($email);

            if ($email[0] == '\\') {
                $text = str_replace($email, mb_substr($email, 1), $text);
            } else {
                $text = str_replace($email, static::emailObfuscator($email), $text);
            }
        }

        return $text;
    }
434465
private function constructAttachment ($attachment, $boundary)
    {

        // Set variables

        $output	= NULL;

        // Add the boundary

        $output	.= '--' . $boundary . $this->_nl;

        // Add the attachment to the message

        $output	.= 'Content-Type: ' . $attachment['type'];

        if ($attachment['name'])
        {
            $output	.= '; name="' . $attachment['name'] . '"';
        }

        $output	.= $this->_nl;
        $output	.= 'Content-Transfer-Encoding: base64' . $this->_nl;

        // Add attachment as plain text if its the body, otherwise add as a file attachment

        if ($attachment['type'] == 'text/plain')
        {
            $output	.= $this->_nl;
        }
        else
        {
            $output	.= 'Content-Disposition: attachment; filename="' . $attachment['name'] . '"' . str_repeat ($this->_nl, 2);
        }

        $output	.= chunk_split (base64_encode ($attachment['data']), 70) . $this->_nl;

        // Return attachment part

        return $output;

    }
35524
public function getMailMIME()
    {
        $result = '';
        $ismultipart = true;
        switch ($this->message_type) {
            case 'inline':
                $result .= $this->headerLine('Content-Type', static::CONTENT_TYPE_MULTIPART_RELATED . ';');
                $result .= $this->textLine(' boundary="' . $this->boundary[1] . '"');
                break;
            case 'attach':
            case 'inline_attach':
            case 'alt_attach':
            case 'alt_inline_attach':
                $result .= $this->headerLine('Content-Type', static::CONTENT_TYPE_MULTIPART_MIXED . ';');
                $result .= $this->textLine(' boundary="' . $this->boundary[1] . '"');
                break;
            case 'alt':
            case 'alt_inline':
                $result .= $this->headerLine('Content-Type', static::CONTENT_TYPE_MULTIPART_ALTERNATIVE . ';');
                $result .= $this->textLine(' boundary="' . $this->boundary[1] . '"');
                break;
            default:
                // Catches case 'plain': and case '':
                $result .= $this->textLine('Content-Type: ' . $this->ContentType . '; charset=' . $this->CharSet);
                $ismultipart = false;
                break;
        }
        // RFC1341 part 5 says 7bit is assumed if not specified
        if (static::ENCODING_7BIT != $this->Encoding) {
            // RFC 2045 section 6.4 says multipart MIME parts may only use 7bit, 8bit or binary CTE
            if ($ismultipart) {
                if (static::ENCODING_8BIT == $this->Encoding) {
                    $result .= $this->headerLine('Content-Transfer-Encoding', static::ENCODING_8BIT);
                }
                // The only remaining alternatives are quoted-printable and base64, which are both 7bit compatible
            } else {
                $result .= $this->headerLine('Content-Transfer-Encoding', $this->Encoding);
            }
        }

        if ('mail' != $this->Mailer) {
            $result .= static::$LE;
        }

        return $result;
    }
1321893
protected function buildTextPart()
    {
        if ($this->body === false) {
            $result = null;
        } else {
            $result = new MimePart($this->body);
            $result->setType(Mime::TYPE_TEXT);
            $result->setCharset(APP_CHARSET);
        }

        return $result;
    }
1006650
private static function encodeBoundaryBlock($boundary, $contentType, $charset, $encoding, $content, $eol = "\n") {
		return '--' . $boundary . $eol
			. 'Content-Type: ' . $contentType. '; charset="' . $charset . '"' . $eol
			. 'Content-Transfer-Encoding: ' . $encoding . $eol . $eol 
			. self::encodeString($content, $encoding, $eol)
			. $eol . $eol;
	}
678121
protected function _attachInlineFiles($boundary = null) {
		if ($boundary === null) {
			$boundary = $this->_boundary;
		}

		$msg = [];
		foreach ($this->_attachments as $filename => $fileInfo) {
			if (empty($fileInfo['contentId'])) {
				continue;
			}
			if (!empty($fileInfo['data'])) {
				$data = $fileInfo['data'];
				$data = chunk_split(base64_encode($data));
			} elseif (!empty($fileInfo['file'])) {
				$data = $this->_readFile($fileInfo['file']);
			} else {
				continue;
			}

			$msg[] = '--' . $boundary;
			$msg[] = 'Content-Type: ' . $fileInfo['mimetype'];
			$msg[] = 'Content-Transfer-Encoding: base64';
			$msg[] = 'Content-ID: <' . $fileInfo['contentId'] . '>';
			$msg[] = 'Content-Disposition: inline; filename="' . $filename . '"';
			$msg[] = '';
			$msg[] = $data;
			$msg[] = '';
		}
		return $msg;
	}
209912
public static function build($body, $files, &$boundary)
    {
        $result = '';
        if(!is_array($body))
        {
            parse_str($body, $body);
        }
        $boundary = Random::letter(8, 16);
        foreach($body as $k => $v)
        {
            $result .= sprintf("--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n", $boundary, $k, $v);
        }
        foreach($files as $file)
        {
            $result .= sprintf("--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\nContent-Type: application/octet-stream\r\n\r\n", $boundary, $file->getClientFilename(), basename($file->getClientFilename())) . $file->getStream()->getContents() . "\r\n";
        }
        $result .= sprintf("--%s--\r\n\r\n", $boundary);
        return $result;
    }
226638
public function CreateBody() {
    $body = '';

    if ($this->sign_key_file) {
      $body .= $this->GetMailMIME();
    }

    $this->SetWordWrap();

    switch($this->message_type) {
      case 'alt':
        $body .= $this->GetBoundary($this->boundary[1], '', 'text/plain', '');
        $body .= $this->EncodeString($this->AltBody, $this->Encoding);
        $body .= $this->LE.$this->LE;
        $body .= $this->GetBoundary($this->boundary[1], '', 'text/html', '');
        $body .= $this->EncodeString($this->Body, $this->Encoding);
        $body .= $this->LE.$this->LE;
        $body .= $this->EndBoundary($this->boundary[1]);
        break;
      case 'plain':
        $body .= $this->EncodeString($this->Body, $this->Encoding);
        break;
      case 'attachments':
        $body .= $this->GetBoundary($this->boundary[1], '', '', '');
        $body .= $this->EncodeString($this->Body, $this->Encoding);
        $body .= $this->LE;
        $body .= $this->AttachAll();
        break;
      case 'alt_attachments':
        $body .= sprintf("--%s%s", $this->boundary[1], $this->LE);
        $body .= sprintf("Content-Type: %s;%s" . "\tboundary=\"%s\"%s", 'multipart/alternative', $this->LE, $this->boundary[2], $this->LE.$this->LE);
        $body .= $this->GetBoundary($this->boundary[2], '', 'text/plain', '') . $this->LE; // Create text body
        $body .= $this->EncodeString($this->AltBody, $this->Encoding);
        $body .= $this->LE.$this->LE;
        $body .= $this->GetBoundary($this->boundary[2], '', 'text/html', '') . $this->LE; // Create the HTML body
        $body .= $this->EncodeString($this->Body, $this->Encoding);
        $body .= $this->LE.$this->LE;
        $body .= $this->EndBoundary($this->boundary[2]);
        $body .= $this->AttachAll();
        break;
    }

    if ($this->IsError()) {
      $body = '';
    } elseif ($this->sign_key_file) {
      try {
        $file = tempnam('', 'mail');
        file_put_contents($file, $body); //TODO check this worked
        $signed = tempnam("", "signed");
        if (@openssl_pkcs7_sign($file, $signed, "file://".$this->sign_cert_file, array("file://".$this->sign_key_file, $this->sign_key_pass), NULL)) {
          @unlink($file);
          @unlink($signed);
          $body = file_get_contents($signed);
        } else {
          @unlink($file);
          @unlink($signed);
          throw new phpmailerException($this->Lang("signing").openssl_error_string());
        }
      } catch (phpmailerException $e) {
        $body = '';
        if ($this->exceptions) {
          throw $e;
        }
      }
    }

    return $body;
  }
1314850
public function getMailMIME()
    {
        $result = '';
        $ismultipart = true;
        switch ($this->message_type) {
            case 'inline':
                $result .= $this->headerLine('Content-Type', 'multipart/related;');
                $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"');
                break;
            case 'attach':
            case 'inline_attach':
            case 'alt_attach':
            case 'alt_inline_attach':
                $result .= $this->headerLine('Content-Type', 'multipart/mixed;');
                $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"');
                break;
            case 'alt':
            case 'alt_inline':
                $result .= $this->headerLine('Content-Type', 'multipart/alternative;');
                $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"');
                break;
            default:
                // Catches case 'plain': and case '':
                $result .= $this->textLine('Content-Type: ' . $this->ContentType . '; charset=' . $this->CharSet);
                $ismultipart = false;
                break;
        }
        // RFC1341 part 5 says 7bit is assumed if not specified
        if ($this->Encoding != '7bit') {
            // RFC 2045 section 6.4 says multipart MIME parts may only use 7bit, 8bit or binary CTE
            if ($ismultipart) {
                if ($this->Encoding == '8bit') {
                    $result .= $this->headerLine('Content-Transfer-Encoding', '8bit');
                }
                // The only remaining alternatives are quoted-printable and base64, which are both 7bit compatible
            } else {
                $result .= $this->headerLine('Content-Transfer-Encoding', $this->Encoding);
            }
        }

        if ($this->Mailer != 'mail') {
            $result .= $this->LE;
        }

        return $result;
    }