1<?php 2 3/* 4 * This file is part of SwiftMailer. 5 * (c) 2004-2009 Chris Corbyn 6 * 7 * For the full copyright and license information, please view the LICENSE 8 * file that was distributed with this source code. 9 */ 10 11/** 12 * A MIME part, in a multipart message. 13 * 14 * @author Chris Corbyn 15 */ 16class Swift_Mime_MimePart extends Swift_Mime_SimpleMimeEntity 17{ 18 /** The format parameter last specified by the user */ 19 protected $userFormat; 20 21 /** The charset last specified by the user */ 22 protected $userCharset; 23 24 /** The delsp parameter last specified by the user */ 25 protected $userDelSp; 26 27 /** The nesting level of this MimePart */ 28 private $nestingLevel = self::LEVEL_ALTERNATIVE; 29 30 /** 31 * Create a new MimePart with $headers, $encoder and $cache. 32 * 33 * @param Swift_Mime_SimpleHeaderSet $headers 34 * @param Swift_Mime_ContentEncoder $encoder 35 * @param Swift_KeyCache $cache 36 * @param Swift_IdGenerator $idGenerator 37 * @param string $charset 38 */ 39 public function __construct(Swift_Mime_SimpleHeaderSet $headers, Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache, Swift_IdGenerator $idGenerator, $charset = null) 40 { 41 parent::__construct($headers, $encoder, $cache, $idGenerator); 42 $this->setContentType('text/plain'); 43 if (null !== $charset) { 44 $this->setCharset($charset); 45 } 46 } 47 48 /** 49 * Set the body of this entity, either as a string, or as an instance of 50 * {@link Swift_OutputByteStream}. 51 * 52 * @param mixed $body 53 * @param string $contentType optional 54 * @param string $charset optional 55 * 56 * @return $this 57 */ 58 public function setBody($body, $contentType = null, $charset = null) 59 { 60 if (isset($charset)) { 61 $this->setCharset($charset); 62 } 63 $body = $this->convertString($body); 64 65 parent::setBody($body, $contentType); 66 67 return $this; 68 } 69 70 /** 71 * Get the character set of this entity. 72 * 73 * @return string 74 */ 75 public function getCharset() 76 { 77 return $this->getHeaderParameter('Content-Type', 'charset'); 78 } 79 80 /** 81 * Set the character set of this entity. 82 * 83 * @param string $charset 84 * 85 * @return $this 86 */ 87 public function setCharset($charset) 88 { 89 $this->setHeaderParameter('Content-Type', 'charset', $charset); 90 if ($charset !== $this->userCharset) { 91 $this->clearCache(); 92 } 93 $this->userCharset = $charset; 94 parent::charsetChanged($charset); 95 96 return $this; 97 } 98 99 /** 100 * Get the format of this entity (i.e. flowed or fixed). 101 * 102 * @return string 103 */ 104 public function getFormat() 105 { 106 return $this->getHeaderParameter('Content-Type', 'format'); 107 } 108 109 /** 110 * Set the format of this entity (flowed or fixed). 111 * 112 * @param string $format 113 * 114 * @return $this 115 */ 116 public function setFormat($format) 117 { 118 $this->setHeaderParameter('Content-Type', 'format', $format); 119 $this->userFormat = $format; 120 121 return $this; 122 } 123 124 /** 125 * Test if delsp is being used for this entity. 126 * 127 * @return bool 128 */ 129 public function getDelSp() 130 { 131 return 'yes' === $this->getHeaderParameter('Content-Type', 'delsp'); 132 } 133 134 /** 135 * Turn delsp on or off for this entity. 136 * 137 * @param bool $delsp 138 * 139 * @return $this 140 */ 141 public function setDelSp($delsp = true) 142 { 143 $this->setHeaderParameter('Content-Type', 'delsp', $delsp ? 'yes' : null); 144 $this->userDelSp = $delsp; 145 146 return $this; 147 } 148 149 /** 150 * Get the nesting level of this entity. 151 * 152 * @see LEVEL_TOP, LEVEL_ALTERNATIVE, LEVEL_MIXED, LEVEL_RELATED 153 * 154 * @return int 155 */ 156 public function getNestingLevel() 157 { 158 return $this->nestingLevel; 159 } 160 161 /** 162 * Receive notification that the charset has changed on this document, or a 163 * parent document. 164 * 165 * @param string $charset 166 */ 167 public function charsetChanged($charset) 168 { 169 $this->setCharset($charset); 170 } 171 172 /** Fix the content-type and encoding of this entity */ 173 protected function fixHeaders() 174 { 175 parent::fixHeaders(); 176 if (count($this->getChildren())) { 177 $this->setHeaderParameter('Content-Type', 'charset', null); 178 $this->setHeaderParameter('Content-Type', 'format', null); 179 $this->setHeaderParameter('Content-Type', 'delsp', null); 180 } else { 181 $this->setCharset($this->userCharset); 182 $this->setFormat($this->userFormat); 183 $this->setDelSp($this->userDelSp); 184 } 185 } 186 187 /** Set the nesting level of this entity */ 188 protected function setNestingLevel($level) 189 { 190 $this->nestingLevel = $level; 191 } 192 193 /** Encode charset when charset is not utf-8 */ 194 protected function convertString($string) 195 { 196 $charset = strtolower($this->getCharset()); 197 if (!in_array($charset, array('utf-8', 'iso-8859-1', 'iso-8859-15', ''))) { 198 // mb_convert_encoding must be the first one to check, since iconv cannot convert some words. 199 if (function_exists('mb_convert_encoding')) { 200 $string = mb_convert_encoding($string, $charset, 'utf-8'); 201 } elseif (function_exists('iconv')) { 202 $string = iconv('utf-8//TRANSLIT//IGNORE', $charset, $string); 203 } else { 204 throw new Swift_SwiftException('No suitable convert encoding function (use UTF-8 as your charset or install the mbstring or iconv extension).'); 205 } 206 207 return $string; 208 } 209 210 return $string; 211 } 212} 213