[ Index ]

MailPress 544

[ Index ]     [ Classes ]     [ Functions ]     [ Variables ]     [ Constants ]     [ Statistics ]    

title

Body

[close]

/mp-includes/Swiftmailer/classes/Swift/Mime/ -> SimpleMimeEntity.php (source)

   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 entity, in a multipart message.
  13   *
  14   * @author Chris Corbyn
  15   */
  16  class Swift_Mime_SimpleMimeEntity implements Swift_Mime_MimeEntity
  17  {
  18      /** A collection of Headers for this mime entity */
  19      private $_headers;
  20  
  21      /** The body as a string, or a stream */
  22      private $_body;
  23  
  24      /** The encoder that encodes the body into a streamable format */
  25      private $_encoder;
  26  
  27      /** The grammar to use for id validation */
  28      private $_grammar;
  29  
  30      /** A mime boundary, if any is used */
  31      private $_boundary;
  32  
  33      /** Mime types to be used based on the nesting level */
  34      private $_compositeRanges = array(
  35          'multipart/mixed' => array(self::LEVEL_TOP, self::LEVEL_MIXED),
  36          'multipart/alternative' => array(self::LEVEL_MIXED, self::LEVEL_ALTERNATIVE),
  37          'multipart/related' => array(self::LEVEL_ALTERNATIVE, self::LEVEL_RELATED),
  38      );
  39  
  40      /** A set of filter rules to define what level an entity should be nested at */
  41      private $_compoundLevelFilters = array();
  42  
  43      /** The nesting level of this entity */
  44      private $_nestingLevel = self::LEVEL_ALTERNATIVE;
  45  
  46      /** A KeyCache instance used during encoding and streaming */
  47      private $_cache;
  48  
  49      /** Direct descendants of this entity */
  50      private $_immediateChildren = array();
  51  
  52      /** All descendants of this entity */
  53      private $_children = array();
  54  
  55      /** The maximum line length of the body of this entity */
  56      private $_maxLineLength = 78;
  57  
  58      /** The order in which alternative mime types should appear */
  59      private $_alternativePartOrder = array(
  60          'text/plain' => 1,
  61          'text/html' => 2,
  62          'multipart/related' => 3,
  63      );
  64  
  65      /** The CID of this entity */
  66      private $_id;
  67  
  68      /** The key used for accessing the cache */
  69      private $_cacheKey;
  70  
  71      protected $_userContentType;
  72  
  73      /**
  74       * Create a new SimpleMimeEntity with $headers, $encoder and $cache.
  75       *
  76       * @param Swift_Mime_HeaderSet      $headers
  77       * @param Swift_Mime_ContentEncoder $encoder
  78       * @param Swift_KeyCache            $cache
  79       * @param Swift_Mime_Grammar        $grammar
  80       */
  81      public function __construct(Swift_Mime_HeaderSet $headers, Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache, Swift_Mime_Grammar $grammar)
  82      {
  83          $this->_cacheKey = md5(uniqid(getmypid().mt_rand(), true));
  84          $this->_cache = $cache;
  85          $this->_headers = $headers;
  86          $this->_grammar = $grammar;
  87          $this->setEncoder($encoder);
  88          $this->_headers->defineOrdering(array('Content-Type', 'Content-Transfer-Encoding'));
  89  
  90          // This array specifies that, when the entire MIME document contains
  91          // $compoundLevel, then for each child within $level, if its Content-Type
  92          // is $contentType then it should be treated as if it's level is
  93          // $neededLevel instead.  I tried to write that unambiguously! :-\
  94          // Data Structure:
  95          // array (
  96          //   $compoundLevel => array(
  97          //     $level => array(
  98          //       $contentType => $neededLevel
  99          //     )
 100          //   )
 101          // )
 102  
 103          $this->_compoundLevelFilters = array(
 104              (self::LEVEL_ALTERNATIVE + self::LEVEL_RELATED) => array(
 105                  self::LEVEL_ALTERNATIVE => array(
 106                      'text/plain' => self::LEVEL_ALTERNATIVE,
 107                      'text/html' => self::LEVEL_RELATED,
 108                      ),
 109                  ),
 110              );
 111  
 112          $this->_id = $this->getRandomId();
 113      }
 114  
 115      /**
 116       * Generate a new Content-ID or Message-ID for this MIME entity.
 117       *
 118       * @return string
 119       */
 120      public function generateId()
 121      {
 122          $this->setId($this->getRandomId());
 123  
 124          return $this->_id;
 125      }
 126  
 127      /**
 128       * Get the {@link Swift_Mime_HeaderSet} for this entity.
 129       *
 130       * @return Swift_Mime_HeaderSet
 131       */
 132      public function getHeaders()
 133      {
 134          return $this->_headers;
 135      }
 136  
 137      /**
 138       * Get the nesting level of this entity.
 139       *
 140       * @see LEVEL_TOP, LEVEL_MIXED, LEVEL_RELATED, LEVEL_ALTERNATIVE
 141       *
 142       * @return int
 143       */
 144      public function getNestingLevel()
 145      {
 146          return $this->_nestingLevel;
 147      }
 148  
 149      /**
 150       * Get the Content-type of this entity.
 151       *
 152       * @return string
 153       */
 154      public function getContentType()
 155      {
 156          return $this->_getHeaderFieldModel('Content-Type');
 157      }
 158  
 159      /**
 160       * Set the Content-type of this entity.
 161       *
 162       * @param string $type
 163       *
 164       * @return Swift_Mime_SimpleMimeEntity
 165       */
 166      public function setContentType($type)
 167      {
 168          $this->_setContentTypeInHeaders($type);
 169          // Keep track of the value so that if the content-type changes automatically
 170          // due to added child entities, it can be restored if they are later removed
 171          $this->_userContentType = $type;
 172  
 173          return $this;
 174      }
 175  
 176      /**
 177       * Get the CID of this entity.
 178       *
 179       * The CID will only be present in headers if a Content-ID header is present.
 180       *
 181       * @return string
 182       */
 183      public function getId()
 184      {
 185          $tmp = (array) $this->_getHeaderFieldModel($this->_getIdField());
 186  
 187          return $this->_headers->has($this->_getIdField()) ? current($tmp) : $this->_id;
 188      }
 189  
 190      /**
 191       * Set the CID of this entity.
 192       *
 193       * @param string $id
 194       *
 195       * @return Swift_Mime_SimpleMimeEntity
 196       */
 197      public function setId($id)
 198      {
 199          if (!$this->_setHeaderFieldModel($this->_getIdField(), $id)) {
 200              $this->_headers->addIdHeader($this->_getIdField(), $id);
 201          }
 202          $this->_id = $id;
 203  
 204          return $this;
 205      }
 206  
 207      /**
 208       * Get the description of this entity.
 209       *
 210       * This value comes from the Content-Description header if set.
 211       *
 212       * @return string
 213       */
 214      public function getDescription()
 215      {
 216          return $this->_getHeaderFieldModel('Content-Description');
 217      }
 218  
 219      /**
 220       * Set the description of this entity.
 221       *
 222       * This method sets a value in the Content-ID header.
 223       *
 224       * @param string $description
 225       *
 226       * @return Swift_Mime_SimpleMimeEntity
 227       */
 228      public function setDescription($description)
 229      {
 230          if (!$this->_setHeaderFieldModel('Content-Description', $description)) {
 231              $this->_headers->addTextHeader('Content-Description', $description);
 232          }
 233  
 234          return $this;
 235      }
 236  
 237      /**
 238       * Get the maximum line length of the body of this entity.
 239       *
 240       * @return int
 241       */
 242      public function getMaxLineLength()
 243      {
 244          return $this->_maxLineLength;
 245      }
 246  
 247      /**
 248       * Set the maximum line length of lines in this body.
 249       *
 250       * Though not enforced by the library, lines should not exceed 1000 chars.
 251       *
 252       * @param int $length
 253       *
 254       * @return Swift_Mime_SimpleMimeEntity
 255       */
 256      public function setMaxLineLength($length)
 257      {
 258          $this->_maxLineLength = $length;
 259  
 260          return $this;
 261      }
 262  
 263      /**
 264       * Get all children added to this entity.
 265       *
 266       * @return Swift_Mime_MimeEntity[]
 267       */
 268      public function getChildren()
 269      {
 270          return $this->_children;
 271      }
 272  
 273      /**
 274       * Set all children of this entity.
 275       *
 276       * @param Swift_Mime_MimeEntity[] $children
 277       * @param int                     $compoundLevel For internal use only
 278       *
 279       * @return Swift_Mime_SimpleMimeEntity
 280       */
 281      public function setChildren(array $children, $compoundLevel = null)
 282      {
 283          // TODO: Try to refactor this logic
 284  
 285          $compoundLevel = isset($compoundLevel)
 286              ? $compoundLevel
 287              : $this->_getCompoundLevel($children)
 288              ;
 289  
 290          $immediateChildren = array();
 291          $grandchildren = array();
 292          $newContentType = $this->_userContentType;
 293  
 294          foreach ($children as $child) {
 295              $level = $this->_getNeededChildLevel($child, $compoundLevel);
 296              if (empty($immediateChildren)) {
 297                  //first iteration
 298                  $immediateChildren = array($child);
 299              } else {
 300                  $nextLevel = $this->_getNeededChildLevel($immediateChildren[0], $compoundLevel);
 301                  if ($nextLevel == $level) {
 302                      $immediateChildren[] = $child;
 303                  } elseif ($level < $nextLevel) {
 304                      // Re-assign immediateChildren to grandchildren
 305                      $grandchildren = array_merge($grandchildren, $immediateChildren);
 306                      // Set new children
 307                      $immediateChildren = array($child);
 308                  } else {
 309                      $grandchildren[] = $child;
 310                  }
 311              }
 312          }
 313  
 314          if (!empty($immediateChildren)) {
 315              $lowestLevel = $this->_getNeededChildLevel($immediateChildren[0], $compoundLevel);
 316  
 317              // Determine which composite media type is needed to accommodate the
 318              // immediate children
 319              foreach ($this->_compositeRanges as $mediaType => $range) {
 320                  if ($lowestLevel > $range[0]
 321                      && $lowestLevel <= $range[1]) {
 322                      $newContentType = $mediaType;
 323                      break;
 324                  }
 325              }
 326  
 327              // Put any grandchildren in a subpart
 328              if (!empty($grandchildren)) {
 329                  $subentity = $this->_createChild();
 330                  $subentity->_setNestingLevel($lowestLevel);
 331                  $subentity->setChildren($grandchildren, $compoundLevel);
 332                  array_unshift($immediateChildren, $subentity);
 333              }
 334          }
 335  
 336          $this->_immediateChildren = $immediateChildren;
 337          $this->_children = $children;
 338          $this->_setContentTypeInHeaders($newContentType);
 339          $this->_fixHeaders();
 340          $this->_sortChildren();
 341  
 342          return $this;
 343      }
 344  
 345      /**
 346       * Get the body of this entity as a string.
 347       *
 348       * @return string
 349       */
 350      public function getBody()
 351      {
 352          return ($this->_body instanceof Swift_OutputByteStream)
 353              ? $this->_readStream($this->_body)
 354              : $this->_body;
 355      }
 356  
 357      /**
 358       * Set the body of this entity, either as a string, or as an instance of
 359       * {@link Swift_OutputByteStream}.
 360       *
 361       * @param mixed  $body
 362       * @param string $contentType optional
 363       *
 364       * @return Swift_Mime_SimpleMimeEntity
 365       */
 366      public function setBody($body, $contentType = null)
 367      {
 368          if ($body !== $this->_body) {
 369              $this->_clearCache();
 370          }
 371  
 372          $this->_body = $body;
 373          if (isset($contentType)) {
 374              $this->setContentType($contentType);
 375          }
 376  
 377          return $this;
 378      }
 379  
 380      /**
 381       * Get the encoder used for the body of this entity.
 382       *
 383       * @return Swift_Mime_ContentEncoder
 384       */
 385      public function getEncoder()
 386      {
 387          return $this->_encoder;
 388      }
 389  
 390      /**
 391       * Set the encoder used for the body of this entity.
 392       *
 393       * @param Swift_Mime_ContentEncoder $encoder
 394       *
 395       * @return Swift_Mime_SimpleMimeEntity
 396       */
 397      public function setEncoder(Swift_Mime_ContentEncoder $encoder)
 398      {
 399          if ($encoder !== $this->_encoder) {
 400              $this->_clearCache();
 401          }
 402  
 403          $this->_encoder = $encoder;
 404          $this->_setEncoding($encoder->getName());
 405          $this->_notifyEncoderChanged($encoder);
 406  
 407          return $this;
 408      }
 409  
 410      /**
 411       * Get the boundary used to separate children in this entity.
 412       *
 413       * @return string
 414       */
 415      public function getBoundary()
 416      {
 417          if (!isset($this->_boundary)) {
 418              $this->_boundary = '_=_swift_v4_'.time().'_'.md5(getmypid().mt_rand().uniqid('', true)).'_=_';
 419          }
 420  
 421          return $this->_boundary;
 422      }
 423  
 424      /**
 425       * Set the boundary used to separate children in this entity.
 426       *
 427       * @param string $boundary
 428       *
 429       * @throws Swift_RfcComplianceException
 430       *
 431       * @return Swift_Mime_SimpleMimeEntity
 432       */
 433      public function setBoundary($boundary)
 434      {
 435          $this->_assertValidBoundary($boundary);
 436          $this->_boundary = $boundary;
 437  
 438          return $this;
 439      }
 440  
 441      /**
 442       * Receive notification that the charset of this entity, or a parent entity
 443       * has changed.
 444       *
 445       * @param string $charset
 446       */
 447      public function charsetChanged($charset)
 448      {
 449          $this->_notifyCharsetChanged($charset);
 450      }
 451  
 452      /**
 453       * Receive notification that the encoder of this entity or a parent entity
 454       * has changed.
 455       *
 456       * @param Swift_Mime_ContentEncoder $encoder
 457       */
 458      public function encoderChanged(Swift_Mime_ContentEncoder $encoder)
 459      {
 460          $this->_notifyEncoderChanged($encoder);
 461      }
 462  
 463      /**
 464       * Get this entire entity as a string.
 465       *
 466       * @return string
 467       */
 468      public function toString()
 469      {
 470          $string = $this->_headers->toString();
 471          $string .= $this->_bodyToString();
 472  
 473          return $string;
 474      }
 475  
 476      /**
 477       * Get this entire entity as a string.
 478       *
 479       * @return string
 480       */
 481      protected function _bodyToString()
 482      {
 483          $string = '';
 484  
 485          if (isset($this->_body) && empty($this->_immediateChildren)) {
 486              if ($this->_cache->hasKey($this->_cacheKey, 'body')) {
 487                  $body = $this->_cache->getString($this->_cacheKey, 'body');
 488              } else {
 489                  $body = "\r\n".$this->_encoder->encodeString($this->getBody(), 0,
 490                      $this->getMaxLineLength()
 491                      );
 492                  $this->_cache->setString($this->_cacheKey, 'body', $body,
 493                      Swift_KeyCache::MODE_WRITE
 494                      );
 495              }
 496              $string .= $body;
 497          }
 498  
 499          if (!empty($this->_immediateChildren)) {
 500              foreach ($this->_immediateChildren as $child) {
 501                  $string .= "\r\n\r\n--".$this->getBoundary()."\r\n";
 502                  $string .= $child->toString();
 503              }
 504              $string .= "\r\n\r\n--".$this->getBoundary()."--\r\n";
 505          }
 506  
 507          return $string;
 508      }
 509  
 510      /**
 511       * Returns a string representation of this object.
 512       *
 513       * @see toString()
 514       *
 515       * @return string
 516       */
 517      public function __toString()
 518      {
 519          return $this->toString();
 520      }
 521  
 522      /**
 523       * Write this entire entity to a {@see Swift_InputByteStream}.
 524       *
 525       * @param Swift_InputByteStream
 526       */
 527      public function toByteStream(Swift_InputByteStream $is)
 528      {
 529          $is->write($this->_headers->toString());
 530          $is->commit();
 531  
 532          $this->_bodyToByteStream($is);
 533      }
 534  
 535      /**
 536       * Write this entire entity to a {@link Swift_InputByteStream}.
 537       *
 538       * @param Swift_InputByteStream
 539       */
 540      protected function _bodyToByteStream(Swift_InputByteStream $is)
 541      {
 542          if (empty($this->_immediateChildren)) {
 543              if (isset($this->_body)) {
 544                  if ($this->_cache->hasKey($this->_cacheKey, 'body')) {
 545                      $this->_cache->exportToByteStream($this->_cacheKey, 'body', $is);
 546                  } else {
 547                      $cacheIs = $this->_cache->getInputByteStream($this->_cacheKey, 'body');
 548                      if ($cacheIs) {
 549                          $is->bind($cacheIs);
 550                      }
 551  
 552                      $is->write("\r\n");
 553  
 554                      if ($this->_body instanceof Swift_OutputByteStream) {
 555                          $this->_body->setReadPointer(0);
 556  
 557                          $this->_encoder->encodeByteStream($this->_body, $is, 0, $this->getMaxLineLength());
 558                      } else {
 559                          $is->write($this->_encoder->encodeString($this->getBody(), 0, $this->getMaxLineLength()));
 560                      }
 561  
 562                      if ($cacheIs) {
 563                          $is->unbind($cacheIs);
 564                      }
 565                  }
 566              }
 567          }
 568  
 569          if (!empty($this->_immediateChildren)) {
 570              foreach ($this->_immediateChildren as $child) {
 571                  $is->write("\r\n\r\n--".$this->getBoundary()."\r\n");
 572                  $child->toByteStream($is);
 573              }
 574              $is->write("\r\n\r\n--".$this->getBoundary()."--\r\n");
 575          }
 576      }
 577  
 578      /**
 579       * Get the name of the header that provides the ID of this entity.
 580       */
 581      protected function _getIdField()
 582      {
 583          return 'Content-ID';
 584      }
 585  
 586      /**
 587       * Get the model data (usually an array or a string) for $field.
 588       */
 589      protected function _getHeaderFieldModel($field)
 590      {
 591          if ($this->_headers->has($field)) {
 592              return $this->_headers->get($field)->getFieldBodyModel();
 593          }
 594      }
 595  
 596      /**
 597       * Set the model data for $field.
 598       */
 599      protected function _setHeaderFieldModel($field, $model)
 600      {
 601          if ($this->_headers->has($field)) {
 602              $this->_headers->get($field)->setFieldBodyModel($model);
 603  
 604              return true;
 605          } else {
 606              return false;
 607          }
 608      }
 609  
 610      /**
 611       * Get the parameter value of $parameter on $field header.
 612       */
 613      protected function _getHeaderParameter($field, $parameter)
 614      {
 615          if ($this->_headers->has($field)) {
 616              return $this->_headers->get($field)->getParameter($parameter);
 617          }
 618      }
 619  
 620      /**
 621       * Set the parameter value of $parameter on $field header.
 622       */
 623      protected function _setHeaderParameter($field, $parameter, $value)
 624      {
 625          if ($this->_headers->has($field)) {
 626              $this->_headers->get($field)->setParameter($parameter, $value);
 627  
 628              return true;
 629          } else {
 630              return false;
 631          }
 632      }
 633  
 634      /**
 635       * Re-evaluate what content type and encoding should be used on this entity.
 636       */
 637      protected function _fixHeaders()
 638      {
 639          if (count($this->_immediateChildren)) {
 640              $this->_setHeaderParameter('Content-Type', 'boundary',
 641                  $this->getBoundary()
 642                  );
 643              $this->_headers->remove('Content-Transfer-Encoding');
 644          } else {
 645              $this->_setHeaderParameter('Content-Type', 'boundary', null);
 646              $this->_setEncoding($this->_encoder->getName());
 647          }
 648      }
 649  
 650      /**
 651       * Get the KeyCache used in this entity.
 652       *
 653       * @return Swift_KeyCache
 654       */
 655      protected function _getCache()
 656      {
 657          return $this->_cache;
 658      }
 659  
 660      /**
 661       * Get the grammar used for validation.
 662       *
 663       * @return Swift_Mime_Grammar
 664       */
 665      protected function _getGrammar()
 666      {
 667          return $this->_grammar;
 668      }
 669  
 670      /**
 671       * Empty the KeyCache for this entity.
 672       */
 673      protected function _clearCache()
 674      {
 675          $this->_cache->clearKey($this->_cacheKey, 'body');
 676      }
 677  
 678      /**
 679       * Returns a random Content-ID or Message-ID.
 680       *
 681       * @return string
 682       */
 683      protected function getRandomId()
 684      {
 685          $idLeft = md5(getmypid().'.'.time().'.'.uniqid(mt_rand(), true));
 686          $idRight = !empty($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'swift.generated';
 687          $id = $idLeft.'@'.$idRight;
 688  
 689          try {
 690              $this->_assertValidId($id);
 691          } catch (Swift_RfcComplianceException $e) {
 692              $id = $idLeft.'@swift.generated';
 693          }
 694  
 695          return $id;
 696      }
 697  
 698      private function _readStream(Swift_OutputByteStream $os)
 699      {
 700          $string = '';
 701          while (false !== $bytes = $os->read(8192)) {
 702              $string .= $bytes;
 703          }
 704  
 705          $os->setReadPointer(0);
 706  
 707          return $string;
 708      }
 709  
 710      private function _setEncoding($encoding)
 711      {
 712          if (!$this->_setHeaderFieldModel('Content-Transfer-Encoding', $encoding)) {
 713              $this->_headers->addTextHeader('Content-Transfer-Encoding', $encoding);
 714          }
 715      }
 716  
 717      private function _assertValidBoundary($boundary)
 718      {
 719          if (!preg_match(
 720              '/^[a-z0-9\'\(\)\+_\-,\.\/:=\?\ ]{0,69}[a-z0-9\'\(\)\+_\-,\.\/:=\?]$/Di',
 721              $boundary)) {
 722              throw new Swift_RfcComplianceException('Mime boundary set is not RFC 2046 compliant.');
 723          }
 724      }
 725  
 726      private function _setContentTypeInHeaders($type)
 727      {
 728          if (!$this->_setHeaderFieldModel('Content-Type', $type)) {
 729              $this->_headers->addParameterizedHeader('Content-Type', $type);
 730          }
 731      }
 732  
 733      private function _setNestingLevel($level)
 734      {
 735          $this->_nestingLevel = $level;
 736      }
 737  
 738      private function _getCompoundLevel($children)
 739      {
 740          $level = 0;
 741          foreach ($children as $child) {
 742              $level |= $child->getNestingLevel();
 743          }
 744  
 745          return $level;
 746      }
 747  
 748      private function _getNeededChildLevel($child, $compoundLevel)
 749      {
 750          $filter = array();
 751          foreach ($this->_compoundLevelFilters as $bitmask => $rules) {
 752              if (($compoundLevel & $bitmask) === $bitmask) {
 753                  $filter = $rules + $filter;
 754              }
 755          }
 756  
 757          $realLevel = $child->getNestingLevel();
 758          $lowercaseType = strtolower($child->getContentType());
 759  
 760          if (isset($filter[$realLevel])
 761              && isset($filter[$realLevel][$lowercaseType])) {
 762              return $filter[$realLevel][$lowercaseType];
 763          } else {
 764              return $realLevel;
 765          }
 766      }
 767  
 768      private function _createChild()
 769      {
 770          return new self($this->_headers->newInstance(),
 771              $this->_encoder, $this->_cache, $this->_grammar);
 772      }
 773  
 774      private function _notifyEncoderChanged(Swift_Mime_ContentEncoder $encoder)
 775      {
 776          foreach ($this->_immediateChildren as $child) {
 777              $child->encoderChanged($encoder);
 778          }
 779      }
 780  
 781      private function _notifyCharsetChanged($charset)
 782      {
 783          $this->_encoder->charsetChanged($charset);
 784          $this->_headers->charsetChanged($charset);
 785          foreach ($this->_immediateChildren as $child) {
 786              $child->charsetChanged($charset);
 787          }
 788      }
 789  
 790      private function _sortChildren()
 791      {
 792          $shouldSort = false;
 793          foreach ($this->_immediateChildren as $child) {
 794              // NOTE: This include alternative parts moved into a related part
 795              if ($child->getNestingLevel() == self::LEVEL_ALTERNATIVE) {
 796                  $shouldSort = true;
 797                  break;
 798              }
 799          }
 800  
 801          // Sort in order of preference, if there is one
 802          if ($shouldSort) {
 803              usort($this->_immediateChildren, array($this, '_childSortAlgorithm'));
 804          }
 805      }
 806  
 807      private function _childSortAlgorithm($a, $b)
 808      {
 809          $typePrefs = array();
 810          $types = array(
 811              strtolower($a->getContentType()),
 812              strtolower($b->getContentType()),
 813              );
 814          foreach ($types as $type) {
 815              $typePrefs[] = (array_key_exists($type, $this->_alternativePartOrder))
 816                  ? $this->_alternativePartOrder[$type]
 817                  : (max($this->_alternativePartOrder) + 1);
 818          }
 819  
 820          return ($typePrefs[0] >= $typePrefs[1]) ? 1 : -1;
 821      }
 822  
 823      // -- Destructor
 824  
 825      /**
 826       * Empties it's own contents from the cache.
 827       */
 828      public function __destruct()
 829      {
 830          $this->_cache->clearAll($this->_cacheKey);
 831      }
 832  
 833      /**
 834       * Throws an Exception if the id passed does not comply with RFC 2822.
 835       *
 836       * @param string $id
 837       *
 838       * @throws Swift_RfcComplianceException
 839       */
 840      private function _assertValidId($id)
 841      {
 842          if (!preg_match(
 843              '/^'.$this->_grammar->getDefinition('id-left').'@'.
 844              $this->_grammar->getDefinition('id-right').'$/D',
 845              $id
 846              )) {
 847              throw new Swift_RfcComplianceException(
 848                  'Invalid ID given <'.$id.'>'
 849                  );
 850          }
 851      }
 852  
 853      /**
 854       * Make a deep copy of object.
 855       */
 856      public function __clone()
 857      {
 858          $this->_headers = clone $this->_headers;
 859          $this->_encoder = clone $this->_encoder;
 860          $this->_cacheKey = uniqid();
 861          $children = array();
 862          foreach ($this->_children as $pos => $child) {
 863              $children[$pos] = clone $child;
 864          }
 865          $this->setChildren($children);
 866      }
 867  }


Generated: Thu Apr 28 18:38:52 2016 Cross-referenced by PHPXref 0.7.1