PlainContentEncoder.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. <?php
  2. /*
  3. * This file is part of SwiftMailer.
  4. * (c) 2004-2009 Chris Corbyn
  5. *
  6. * For the full copyright and license information, please view the LICENSE
  7. * file that was distributed with this source code.
  8. */
  9. /**
  10. * Handles binary/7/8-bit Transfer Encoding in Swift Mailer.
  11. *
  12. * @author Chris Corbyn
  13. */
  14. class Swift_Mime_ContentEncoder_PlainContentEncoder implements Swift_Mime_ContentEncoder
  15. {
  16. /**
  17. * The name of this encoding scheme (probably 7bit or 8bit).
  18. *
  19. * @var string
  20. */
  21. private $_name;
  22. /**
  23. * True if canonical transformations should be done.
  24. *
  25. * @var bool
  26. */
  27. private $_canonical;
  28. /**
  29. * Creates a new PlainContentEncoder with $name (probably 7bit or 8bit).
  30. *
  31. * @param string $name
  32. * @param bool $canonical If canonicalization transformation should be done.
  33. */
  34. public function __construct($name, $canonical = false)
  35. {
  36. $this->_name = $name;
  37. $this->_canonical = $canonical;
  38. }
  39. /**
  40. * Encode a given string to produce an encoded string.
  41. *
  42. * @param string $string
  43. * @param int $firstLineOffset ignored
  44. * @param int $maxLineLength - 0 means no wrapping will occur
  45. *
  46. * @return string
  47. */
  48. public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0)
  49. {
  50. if ($this->_canonical) {
  51. $string = $this->_canonicalize($string);
  52. }
  53. return $this->_safeWordWrap($string, $maxLineLength, "\r\n");
  54. }
  55. /**
  56. * Encode stream $in to stream $out.
  57. *
  58. * @param Swift_OutputByteStream $os
  59. * @param Swift_InputByteStream $is
  60. * @param int $firstLineOffset ignored
  61. * @param int $maxLineLength optional, 0 means no wrapping will occur
  62. */
  63. public function encodeByteStream(Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, $maxLineLength = 0)
  64. {
  65. $leftOver = '';
  66. while (false !== $bytes = $os->read(8192)) {
  67. $toencode = $leftOver . $bytes;
  68. if ($this->_canonical) {
  69. $toencode = $this->_canonicalize($toencode);
  70. }
  71. $wrapped = $this->_safeWordWrap($toencode, $maxLineLength, "\r\n");
  72. $lastLinePos = strrpos($wrapped, "\r\n");
  73. $leftOver = substr($wrapped, $lastLinePos);
  74. $wrapped = substr($wrapped, 0, $lastLinePos);
  75. $is->write($wrapped);
  76. }
  77. if (strlen($leftOver)) {
  78. $is->write($leftOver);
  79. }
  80. }
  81. /**
  82. * Get the name of this encoding scheme.
  83. *
  84. * @return string
  85. */
  86. public function getName()
  87. {
  88. return $this->_name;
  89. }
  90. /**
  91. * Not used.
  92. */
  93. public function charsetChanged($charset)
  94. {
  95. }
  96. /**
  97. * A safer (but weaker) wordwrap for unicode.
  98. *
  99. * @param string $string
  100. * @param int $length
  101. * @param string $le
  102. *
  103. * @return string
  104. */
  105. private function _safeWordwrap($string, $length = 75, $le = "\r\n")
  106. {
  107. if (0 >= $length) {
  108. return $string;
  109. }
  110. $originalLines = explode($le, $string);
  111. $lines = array();
  112. $lineCount = 0;
  113. foreach ($originalLines as $originalLine) {
  114. $lines[] = '';
  115. $currentLine =& $lines[$lineCount++];
  116. //$chunks = preg_split('/(?<=[\ \t,\.!\?\-&\+\/])/', $originalLine);
  117. $chunks = preg_split('/(?<=\s)/', $originalLine);
  118. foreach ($chunks as $chunk) {
  119. if (0 != strlen($currentLine)
  120. && strlen($currentLine . $chunk) > $length)
  121. {
  122. $lines[] = '';
  123. $currentLine =& $lines[$lineCount++];
  124. }
  125. $currentLine .= $chunk;
  126. }
  127. }
  128. return implode("\r\n", $lines);
  129. }
  130. /**
  131. * Canonicalize string input (fix CRLF).
  132. *
  133. * @param string $string
  134. *
  135. * @return string
  136. */
  137. private function _canonicalize($string)
  138. {
  139. return str_replace(
  140. array("\r\n", "\r", "\n"),
  141. array("\n", "\n", "\r\n"),
  142. $string
  143. );
  144. }
  145. }