CakePHP
  • Documentation
    • Book
    • API
    • Videos
    • Reporting Security Issues
    • Privacy Policy
    • Logos & Trademarks
  • Business Solutions
  • Swag
  • Road Trip
  • Team
  • Community
    • Community
    • Get Involved
    • Issues (GitHub)
    • Bakery
    • Featured Resources
    • Training
    • Meetups
    • My CakePHP
    • CakeFest
    • Newsletter
    • Linkedin
    • YouTube
    • Facebook
    • Twitter
    • Mastodon
    • Help & Support
    • Forum
    • Stack Overflow
    • Slack
    • Paid Support
CakePHP

C CakePHP 2.0 API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 2.0
      • 4.2
      • 4.1
      • 4.0
      • 3.9
      • 3.8
      • 3.7
      • 3.6
      • 3.5
      • 3.4
      • 3.3
      • 3.2
      • 3.1
      • 3.0
      • 2.10
      • 2.9
      • 2.8
      • 2.7
      • 2.6
      • 2.5
      • 2.4
      • 2.3
      • 2.2
      • 2.1
      • 2.0
      • 1.3
      • 1.2

Packages

  • Cake
    • Cache
      • Engine
    • Configure
    • Console
      • Command
        • Task
    • Controller
      • Component
        • Auth
    • Core
    • Error
    • I18n
    • Log
      • Engine
    • Model
      • Behavior
      • Datasource
        • Database
        • Session
    • Network
      • Email
      • Http
    • Routing
      • Route
    • TestSuite
      • Coverage
      • Fixture
      • Reporter
    • Utility
    • View
      • Helper

Classes

  • AbstractTransport
  • CakeEmail
  • DebugTransport
  • MailTransport
  • SmtpTransport
   1: <?php
   2: /**
   3:  * Cake E-Mail
   4:  *
   5:  * PHP 5
   6:  *
   7:  * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
   8:  * Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
   9:  *
  10:  * Licensed under The MIT License
  11:  * Redistributions of files must retain the above copyright notice.
  12:  *
  13:  * @copyright     Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
  14:  * @link          http://cakephp.org CakePHP(tm) Project
  15:  * @package       Cake.Network.Email
  16:  * @since         CakePHP(tm) v 2.0.0
  17:  * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
  18:  */
  19: 
  20: App::uses('Validation', 'Utility');
  21: App::uses('Multibyte', 'I18n');
  22: App::uses('AbstractTransport', 'Network/Email');
  23: App::uses('String', 'Utility');
  24: App::uses('View', 'View');
  25: App::import('I18n', 'Multibyte');
  26: 
  27: /**
  28:  * Cake e-mail class.
  29:  *
  30:  * This class is used for handling Internet Message Format based
  31:  * based on the standard outlined in http://www.rfc-editor.org/rfc/rfc2822.txt
  32:  *
  33:  * @package       Cake.Network.Email
  34:  */
  35: class CakeEmail {
  36: /**
  37:  * Default X-Mailer
  38:  *
  39:  * @constant EMAIL_CLIENT
  40:  */
  41:     const EMAIL_CLIENT = 'CakePHP Email';
  42: 
  43: /**
  44:  * Line length - no should more - RFC 2822 - 2.1.1
  45:  *
  46:  * @constant LINE_LENGTH_SHOULD
  47:  */
  48:     const LINE_LENGTH_SHOULD = 78;
  49: 
  50: /**
  51:  * Line length - no must more - RFC 2822 - 2.1.1
  52:  *
  53:  * @constant LINE_LENGTH_MUST
  54:  */
  55:     const LINE_LENGTH_MUST = 998;
  56: 
  57: /**
  58:  * Type of message - HTML
  59:  *
  60:  * @constant MESSAGE_HTML
  61:  */
  62:     const MESSAGE_HTML = 'html';
  63: 
  64: /**
  65:  * Type of message - TEXT
  66:  *
  67:  * @constant MESSAGE_TEXT
  68:  */
  69:     const MESSAGE_TEXT = 'text';
  70: 
  71: /**
  72:  * Recipient of the email
  73:  *
  74:  * @var array
  75:  */
  76:     protected $_to = array();
  77: 
  78: /**
  79:  * The mail which the email is sent from
  80:  *
  81:  * @var array
  82:  */
  83:     protected $_from = array();
  84: 
  85: /**
  86:  * The sender email
  87:  *
  88:  * @var array();
  89:  */
  90:     protected $_sender = array();
  91: 
  92: /**
  93:  * The email the recipient will reply to
  94:  *
  95:  * @var array
  96:  */
  97:     protected $_replyTo = array();
  98: 
  99: /**
 100:  * The read receipt email
 101:  *
 102:  * @var array
 103:  */
 104:     protected $_readReceipt = array();
 105: 
 106: /**
 107:  * The mail that will be used in case of any errors like
 108:  * - Remote mailserver down
 109:  * - Remote user has exceeded his quota
 110:  * - Unknown user
 111:  *
 112:  * @var array
 113:  */
 114:     protected $_returnPath = array();
 115: 
 116: /**
 117:  * Carbon Copy
 118:  *
 119:  * List of email's that should receive a copy of the email.
 120:  * The Recipient WILL be able to see this list
 121:  *
 122:  * @var array
 123:  */
 124:     protected $_cc = array();
 125: 
 126: /**
 127:  * Blind Carbon Copy
 128:  *
 129:  * List of email's that should receive a copy of the email.
 130:  * The Recipient WILL NOT be able to see this list
 131:  *
 132:  * @var array
 133:  */
 134:     protected $_bcc = array();
 135: 
 136: /**
 137:  * Message ID
 138:  *
 139:  * @var mixed True to generate, False to ignore, String with value
 140:  */
 141:     protected $_messageId = true;
 142: 
 143: /**
 144:  * The subject of the email
 145:  *
 146:  * @var string
 147:  */
 148:     protected $_subject = '';
 149: 
 150: /**
 151:  * Associative array of a user defined headers
 152:  * Keys will be prefixed 'X-' as per RFC2822 Section 4.7.5
 153:  *
 154:  * @var array
 155:  */
 156:     protected $_headers = array();
 157: 
 158: /**
 159:  * Layout for the View
 160:  *
 161:  * @var string
 162:  */
 163:     protected $_layout = 'default';
 164: 
 165: /**
 166:  * Template for the view
 167:  *
 168:  * @var string
 169:  */
 170:     protected $_template = '';
 171: 
 172: /**
 173:  * View for render
 174:  *
 175:  * @var string
 176:  */
 177:     protected $_viewRender = 'View';
 178: 
 179: /**
 180:  * Vars to sent to render
 181:  *
 182:  * @var array
 183:  */
 184:     protected $_viewVars = array();
 185: 
 186: /**
 187:  * Helpers to be used in the render
 188:  *
 189:  * @var array
 190:  */
 191:     protected $_helpers = array('Html');
 192: 
 193: /**
 194:  * Text message
 195:  *
 196:  * @var string
 197:  */
 198:     protected $_textMessage = '';
 199: 
 200: /**
 201:  * Html message
 202:  *
 203:  * @var string
 204:  */
 205:     protected $_htmlMessage = '';
 206: 
 207: /**
 208:  * Final message to send
 209:  *
 210:  * @var array
 211:  */
 212:     protected $_message = array();
 213: 
 214: /**
 215:  * Available formats to be sent.
 216:  *
 217:  * @var array
 218:  */
 219:     protected $_emailFormatAvailable = array('text', 'html', 'both');
 220: 
 221: /**
 222:  * What format should the email be sent in
 223:  *
 224:  * @var string
 225:  */
 226:     protected $_emailFormat = 'text';
 227: 
 228: /**
 229:  * What method should the email be sent
 230:  *
 231:  * @var string
 232:  */
 233:     protected $_transportName = 'Mail';
 234: 
 235: /**
 236:  * Instance of transport class
 237:  *
 238:  * @var AbstractTransport
 239:  */
 240:     protected $_transportClass = null;
 241: 
 242: /**
 243:  * Charset the email body is sent in
 244:  *
 245:  *
 246:  * @var string
 247:  */
 248:     public $charset = 'utf-8';
 249: 
 250: /**
 251:  * Charset the email header is sent in
 252:  * If null, the $charset property will be used as default
 253:  * @var string
 254:  */
 255:     public $headerCharset = null;
 256: 
 257: /**
 258:  * The application wide charset, used to encode headers and body
 259:  * @var string
 260:  */
 261:     public $_appCharset = null;
 262: 
 263: /**
 264:  * List of files that should be attached to the email.
 265:  *
 266:  * Only absolute paths
 267:  *
 268:  * @var array
 269:  */
 270:     protected $_attachments = array();
 271: 
 272: /**
 273:  * If set, boundary to use for multipart mime messages
 274:  *
 275:  * @var string
 276:  */
 277:     protected $_boundary = null;
 278: 
 279: /**
 280:  * Configuration to transport
 281:  *
 282:  * @var mixed
 283:  */
 284:     protected $_config = array();
 285: 
 286: /**
 287:  * 8Bit character sets
 288:  *
 289:  * @var array
 290:  */
 291:     protected $_charset8bit = array('UTF-8', 'SHIFT_JIS');
 292: 
 293: /**
 294:  * Constructor
 295:  * @param mixed $config Array of configs, or string to load configs from email.php
 296:  *
 297:  */
 298:     public function __construct($config = null) {
 299:         $this->_appCharset = Configure::read('App.encoding');
 300:         if ($this->_appCharset !== null) {
 301:             $this->charset = $this->_appCharset;
 302:         }
 303:         if ($config) {
 304:             $this->config($config);
 305:         }
 306:         if (empty($this->headerCharset)) {
 307:             $this->headerCharset = $this->charset;
 308:         }
 309:     }
 310: 
 311: /**
 312:  * From
 313:  *
 314:  * @param mixed $email
 315:  * @param string $name
 316:  * @return mixed
 317:  * @throws SocketException
 318:  */
 319:     public function from($email = null, $name = null) {
 320:         if ($email === null) {
 321:             return $this->_from;
 322:         }
 323:         return $this->_setEmailSingle('_from', $email, $name, __d('cake_dev', 'From requires only 1 email address.'));
 324:     }
 325: 
 326: /**
 327:  * Sender
 328:  *
 329:  * @param mixed $email
 330:  * @param string $name
 331:  * @return mixed
 332:  * @throws SocketException
 333:  */
 334:     public function sender($email = null, $name = null) {
 335:         if ($email === null) {
 336:             return $this->_sender;
 337:         }
 338:         return $this->_setEmailSingle('_sender', $email, $name, __d('cake_dev', 'Sender requires only 1 email address.'));
 339:     }
 340: 
 341: /**
 342:  * Reply-To
 343:  *
 344:  * @param mixed $email
 345:  * @param string $name
 346:  * @return mixed
 347:  * @throws SocketException
 348:  */
 349:     public function replyTo($email = null, $name = null) {
 350:         if ($email === null) {
 351:             return $this->_replyTo;
 352:         }
 353:         return $this->_setEmailSingle('_replyTo', $email, $name, __d('cake_dev', 'Reply-To requires only 1 email address.'));
 354:     }
 355: 
 356: /**
 357:  * Read Receipt (Disposition-Notification-To header)
 358:  *
 359:  * @param mixed $email
 360:  * @param string $name
 361:  * @return mixed
 362:  * @throws SocketException
 363:  */
 364:     public function readReceipt($email = null, $name = null) {
 365:         if ($email === null) {
 366:             return $this->_readReceipt;
 367:         }
 368:         return $this->_setEmailSingle('_readReceipt', $email, $name, __d('cake_dev', 'Disposition-Notification-To requires only 1 email address.'));
 369:     }
 370: 
 371: /**
 372:  * Return Path
 373:  *
 374:  * @param mixed $email
 375:  * @param string $name
 376:  * @return mixed
 377:  * @throws SocketException
 378:  */
 379:     public function returnPath($email = null, $name = null) {
 380:         if ($email === null) {
 381:             return $this->_returnPath;
 382:         }
 383:         return $this->_setEmailSingle('_returnPath', $email, $name, __d('cake_dev', 'Return-Path requires only 1 email address.'));
 384:     }
 385: 
 386: /**
 387:  * To
 388:  *
 389:  * @param mixed $email Null to get, String with email, Array with email as key, name as value or email as value (without name)
 390:  * @param string $name
 391:  * @return mixed
 392:  */
 393:     public function to($email = null, $name = null) {
 394:         if ($email === null) {
 395:             return $this->_to;
 396:         }
 397:         return $this->_setEmail('_to', $email, $name);
 398:     }
 399: 
 400: /**
 401:  * Add To
 402:  *
 403:  * @param mixed $email String with email, Array with email as key, name as value or email as value (without name)
 404:  * @param string $name
 405:  * @return CakeEmail $this
 406:  */
 407:     public function addTo($email, $name = null) {
 408:         return $this->_addEmail('_to', $email, $name);
 409:     }
 410: 
 411: /**
 412:  * Cc
 413:  *
 414:  * @param mixed $email String with email, Array with email as key, name as value or email as value (without name)
 415:  * @param string $name
 416:  * @return mixed
 417:  */
 418:     public function cc($email = null, $name = null) {
 419:         if ($email === null) {
 420:             return $this->_cc;
 421:         }
 422:         return $this->_setEmail('_cc', $email, $name);
 423:     }
 424: 
 425: /**
 426:  * Add Cc
 427:  *
 428:  * @param mixed $email String with email, Array with email as key, name as value or email as value (without name)
 429:  * @param string $name
 430:  * @return CakeEmail $this
 431:  */
 432:     public function addCc($email, $name = null) {
 433:         return $this->_addEmail('_cc', $email, $name);
 434:     }
 435: 
 436: /**
 437:  * Bcc
 438:  *
 439:  * @param mixed $email String with email, Array with email as key, name as value or email as value (without name)
 440:  * @param string $name
 441:  * @return mixed
 442:  */
 443:     public function bcc($email = null, $name = null) {
 444:         if ($email === null) {
 445:             return $this->_bcc;
 446:         }
 447:         return $this->_setEmail('_bcc', $email, $name);
 448:     }
 449: 
 450: /**
 451:  * Add Bcc
 452:  *
 453:  * @param mixed $email String with email, Array with email as key, name as value or email as value (without name)
 454:  * @param string $name
 455:  * @return CakeEmail $this
 456:  */
 457:     public function addBcc($email, $name = null) {
 458:         return $this->_addEmail('_bcc', $email, $name);
 459:     }
 460: 
 461: /**
 462:  * Set email
 463:  *
 464:  * @param string $varName
 465:  * @param mixed $email
 466:  * @param mixed $name
 467:  * @return CakeEmail $this
 468:  * @throws SocketException
 469:  */
 470:     protected function _setEmail($varName, $email, $name) {
 471:         if (!is_array($email)) {
 472:             if (!Validation::email($email)) {
 473:                 throw new SocketException(__d('cake_dev', 'Invalid email: "%s"', $email));
 474:             }
 475:             if ($name === null) {
 476:                 $name = $email;
 477:             }
 478:             $this->{$varName} = array($email => $name);
 479:             return $this;
 480:         }
 481:         $list = array();
 482:         foreach ($email as $key => $value) {
 483:             if (is_int($key)) {
 484:                 $key = $value;
 485:             }
 486:             if (!Validation::email($key)) {
 487:                 throw new SocketException(__d('cake_dev', 'Invalid email: "%s"', $key));
 488:             }
 489:             $list[$key] = $value;
 490:         }
 491:         $this->{$varName} = $list;
 492:         return $this;
 493:     }
 494: 
 495: /**
 496:  * Set only 1 email
 497:  *
 498:  * @param string $varName
 499:  * @param mixed $email
 500:  * @param string $name
 501:  * @param string $throwMessage
 502:  * @return CakeEmail $this
 503:  * @throws SocketException
 504:  */
 505:     protected function _setEmailSingle($varName, $email, $name, $throwMessage) {
 506:         $current = $this->{$varName};
 507:         $this->_setEmail($varName, $email, $name);
 508:         if (count($this->{$varName}) !== 1) {
 509:             $this->{$varName} = $current;
 510:             throw new SocketException($throwMessage);
 511:         }
 512:         return $this;
 513:     }
 514: 
 515: /**
 516:  * Add email
 517:  *
 518:  * @param string $varName
 519:  * @param mixed $email
 520:  * @param mixed $name
 521:  * @return CakeEmail $this
 522:  * @throws SocketException
 523:  */
 524:     protected function _addEmail($varName, $email, $name) {
 525:         if (!is_array($email)) {
 526:             if (!Validation::email($email)) {
 527:                 throw new SocketException(__d('cake_dev', 'Invalid email: "%s"', $email));
 528:             }
 529:             if ($name === null) {
 530:                 $name = $email;
 531:             }
 532:             $this->{$varName}[$email] = $name;
 533:             return $this;
 534:         }
 535:         $list = array();
 536:         foreach ($email as $key => $value) {
 537:             if (is_int($key)) {
 538:                 $key = $value;
 539:             }
 540:             if (!Validation::email($key)) {
 541:                 throw new SocketException(__d('cake_dev', 'Invalid email: "%s"', $key));
 542:             }
 543:             $list[$key] = $value;
 544:         }
 545:         $this->{$varName} = array_merge($this->{$varName}, $list);
 546:         return $this;
 547:     }
 548: 
 549: /**
 550:  * Get/Set Subject.
 551:  *
 552:  * @param null|string $subject
 553:  * @return mixed
 554:  */
 555:     public function subject($subject = null) {
 556:         if ($subject === null) {
 557:             return $this->_subject;
 558:         }
 559:         $this->_subject = $this->_encode((string)$subject);
 560:         return $this;
 561:     }
 562: 
 563: /**
 564:  * Sets headers for the message
 565:  *
 566:  * @param array $headers Associative array containing headers to be set.
 567:  * @return CakeEmail $this
 568:  * @throws SocketException
 569:  */
 570:     public function setHeaders($headers) {
 571:         if (!is_array($headers)) {
 572:             throw new SocketException(__d('cake_dev', '$headers should be an array.'));
 573:         }
 574:         $this->_headers = $headers;
 575:         return $this;
 576:     }
 577: 
 578: /**
 579:  * Add header for the message
 580:  *
 581:  * @param array $headers
 582:  * @return object $this
 583:  * @throws SocketException
 584:  */
 585:     public function addHeaders($headers) {
 586:         if (!is_array($headers)) {
 587:             throw new SocketException(__d('cake_dev', '$headers should be an array.'));
 588:         }
 589:         $this->_headers = array_merge($this->_headers, $headers);
 590:         return $this;
 591:     }
 592: 
 593: /**
 594:  * Get list of headers
 595:  *
 596:  * ### Includes:
 597:  *
 598:  * - `from`
 599:  * - `replyTo`
 600:  * - `readReceipt`
 601:  * - `returnPath`
 602:  * - `to`
 603:  * - `cc`
 604:  * - `bcc`
 605:  * - `subject`
 606:  *
 607:  * @param array $include
 608:  * @return array
 609:  */
 610:     public function getHeaders($include = array()) {
 611:         if ($include == array_values($include)) {
 612:             $include = array_fill_keys($include, true);
 613:         }
 614:         $defaults = array_fill_keys(array('from', 'sender', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'bcc', 'subject'), false);
 615:         $include += $defaults;
 616: 
 617:         $headers = array();
 618:         $relation = array(
 619:             'from' => 'From',
 620:             'replyTo' => 'Reply-To',
 621:             'readReceipt' => 'Disposition-Notification-To',
 622:             'returnPath' => 'Return-Path'
 623:         );
 624:         foreach ($relation as $var => $header) {
 625:             if ($include[$var]) {
 626:                 $var = '_' . $var;
 627:                 $headers[$header] = current($this->_formatAddress($this->{$var}));
 628:             }
 629:         }
 630:         if ($include['sender']) {
 631:             if (key($this->_sender) === key($this->_from)) {
 632:                 $headers['Sender'] = '';
 633:             } else {
 634:                 $headers['Sender'] = current($this->_formatAddress($this->_sender));
 635:             }
 636:         }
 637: 
 638:         foreach (array('to', 'cc', 'bcc') as $var) {
 639:             if ($include[$var]) {
 640:                 $classVar = '_' . $var;
 641:                 $headers[ucfirst($var)] = implode(', ', $this->_formatAddress($this->{$classVar}));
 642:             }
 643:         }
 644: 
 645:         $headers += $this->_headers;
 646:         if (!isset($headers['X-Mailer'])) {
 647:             $headers['X-Mailer'] = self::EMAIL_CLIENT;
 648:         }
 649:         if (!isset($headers['Date'])) {
 650:             $headers['Date'] = date(DATE_RFC2822);
 651:         }
 652:         if ($this->_messageId !== false) {
 653:             if ($this->_messageId === true) {
 654:                 $headers['Message-ID'] = '<' . str_replace('-', '', String::UUID()) . '@' . env('HTTP_HOST') . '>';
 655:             } else {
 656:                 $headers['Message-ID'] = $this->_messageId;
 657:             }
 658:         }
 659: 
 660:         if ($include['subject']) {
 661:             $headers['Subject'] = $this->_subject;
 662:         }
 663: 
 664:         $headers['MIME-Version'] = '1.0';
 665:         if (!empty($this->_attachments) || $this->_emailFormat === 'both') {
 666:             $headers['Content-Type'] = 'multipart/mixed; boundary="' . $this->_boundary . '"';
 667:         } elseif ($this->_emailFormat === 'text') {
 668:             $headers['Content-Type'] = 'text/plain; charset=' . $this->charset;
 669:         } elseif ($this->_emailFormat === 'html') {
 670:             $headers['Content-Type'] = 'text/html; charset=' . $this->charset;
 671:         }
 672:         $headers['Content-Transfer-Encoding'] = $this->_getContentTransferEncoding();
 673: 
 674:         return $headers;
 675:     }
 676: 
 677: /**
 678:  * Format addresses
 679:  *
 680:  * @param array $address
 681:  * @return array
 682:  */
 683:     protected function _formatAddress($address) {
 684:         $return = array();
 685:         foreach ($address as $email => $alias) {
 686:             if ($email === $alias) {
 687:                 $return[] = $email;
 688:             } else {
 689:                 $return[] = sprintf('%s <%s>', $this->_encode($alias), $email);
 690:             }
 691:         }
 692:         return $return;
 693:     }
 694: 
 695: /**
 696:  * Template and layout
 697:  *
 698:  * @param mixed $template Template name or null to not use
 699:  * @param mixed $layout Layout name or null to not use
 700:  * @return mixed
 701:  */
 702:     public function template($template = false, $layout = false) {
 703:         if ($template === false) {
 704:             return array(
 705:                 'template' => $this->_template,
 706:                 'layout' => $this->_layout
 707:             );
 708:         }
 709:         $this->_template = $template;
 710:         if ($layout !== false) {
 711:             $this->_layout = $layout;
 712:         }
 713:         return $this;
 714:     }
 715: 
 716: /**
 717:  * View class for render
 718:  *
 719:  * @param string $viewClass
 720:  * @return mixed
 721:  */
 722:     public function viewRender($viewClass = null) {
 723:         if ($viewClass === null) {
 724:             return $this->_viewRender;
 725:         }
 726:         $this->_viewRender = $viewClass;
 727:         return $this;
 728:     }
 729: 
 730: /**
 731:  * Variables to be set on render
 732:  *
 733:  * @param array $viewVars
 734:  * @return mixed
 735:  */
 736:     public function viewVars($viewVars = null) {
 737:         if ($viewVars === null) {
 738:             return $this->_viewVars;
 739:         }
 740:         $this->_viewVars = array_merge($this->_viewVars, (array)$viewVars);
 741:         return $this;
 742:     }
 743: 
 744: /**
 745:  * Helpers to be used in render
 746:  *
 747:  * @param array $helpers
 748:  * @return mixed
 749:  */
 750:     public function helpers($helpers = null) {
 751:         if ($helpers === null) {
 752:             return $this->_helpers;
 753:         }
 754:         $this->_helpers = (array)$helpers;
 755:         return $this;
 756:     }
 757: 
 758: /**
 759:  * Email format
 760:  *
 761:  * @param string $format
 762:  * @return mixed
 763:  * @throws SocketException
 764:  */
 765:     public function emailFormat($format = null) {
 766:         if ($format === null) {
 767:             return $this->_emailFormat;
 768:         }
 769:         if (!in_array($format, $this->_emailFormatAvailable)) {
 770:             throw new SocketException(__d('cake_dev', 'Format not available.'));
 771:         }
 772:         $this->_emailFormat = $format;
 773:         return $this;
 774:     }
 775: 
 776: /**
 777:  * Transport name
 778:  *
 779:  * @param string $name
 780:  * @return mixed
 781:  */
 782:     public function transport($name = null) {
 783:         if ($name === null) {
 784:             return $this->_transportName;
 785:         }
 786:         $this->_transportName = (string)$name;
 787:         $this->_transportClass = null;
 788:         return $this;
 789:     }
 790: 
 791: /**
 792:  * Return the transport class
 793:  *
 794:  * @return CakeEmail
 795:  * @throws SocketException
 796:  */
 797:     public function transportClass() {
 798:         if ($this->_transportClass) {
 799:             return $this->_transportClass;
 800:         }
 801:         list($plugin, $transportClassname) = pluginSplit($this->_transportName, true);
 802:         $transportClassname .= 'Transport';
 803:         App::uses($transportClassname, $plugin . 'Network/Email');
 804:         if (!class_exists($transportClassname)) {
 805:             throw new SocketException(__d('cake_dev', 'Class "%s" not found.', $transportClassname));
 806:         } elseif (!method_exists($transportClassname, 'send')) {
 807:             throw new SocketException(__d('cake_dev', 'The "%s" do not have send method.', $transportClassname));
 808:         }
 809: 
 810:         return $this->_transportClass = new $transportClassname();
 811:     }
 812: 
 813: /**
 814:  * Message-ID
 815:  *
 816:  * @param mixed $message True to generate a new Message-ID, False to ignore (not send in email), String to set as Message-ID
 817:  * @return mixed
 818:  * @throws SocketException
 819:  */
 820:     public function messageId($message = null) {
 821:         if ($message === null) {
 822:             return $this->_messageId;
 823:         }
 824:         if (is_bool($message)) {
 825:             $this->_messageId = $message;
 826:         } else {
 827:             if (!preg_match('/^\<.+@.+\>$/', $message)) {
 828:                 throw new SocketException(__d('cake_dev', 'Invalid format to Message-ID. The text should be something like "<[email protected]>"'));
 829:             }
 830:             $this->_messageId = $message;
 831:         }
 832:         return $this;
 833:     }
 834: 
 835: /**
 836:  * Add attachments to the email message
 837:  *
 838:  * Attachments can be defined in a few forms depending on how much control you need:
 839:  *
 840:  * Attach a single file:
 841:  *
 842:  * {{{
 843:  * $email->attachments('path/to/file');
 844:  * }}}
 845:  *
 846:  * Attach a file with a different filename:
 847:  *
 848:  * {{{
 849:  * $email->attachments(array('custom_name.txt' => 'path/to/file.txt'));
 850:  * }}}
 851:  *
 852:  * Attach a file and specify additional properties:
 853:  *
 854:  * {{{
 855:  * $email->attachments(array('custom_name.png' => array(
 856:  *      'file' => 'path/to/file',
 857:  *      'mimetype' => 'image/png',
 858:  *      'contentId' => 'abc123'
 859:  * ));
 860:  * }}}
 861:  *
 862:  * The `contentId` key allows you to specify an inline attachment. In your email text, you
 863:  * can use `<img src="cid:abc123" />` to display the image inline.
 864:  *
 865:  * @param mixed $attachments String with the filename or array with filenames
 866:  * @return mixed Either the array of attachments when getting or $this when setting.
 867:  * @throws SocketException
 868:  */
 869:     public function attachments($attachments = null) {
 870:         if ($attachments === null) {
 871:             return $this->_attachments;
 872:         }
 873:         $attach = array();
 874:         foreach ((array)$attachments as $name => $fileInfo) {
 875:             if (!is_array($fileInfo)) {
 876:                 $fileInfo = array('file' => $fileInfo);
 877:             }
 878:             if (!isset($fileInfo['file'])) {
 879:                 throw new SocketException(__d('cake_dev', 'File not specified.'));
 880:             }
 881:             $fileInfo['file'] = realpath($fileInfo['file']);
 882:             if ($fileInfo['file'] === false || !file_exists($fileInfo['file'])) {
 883:                 throw new SocketException(__d('cake_dev', 'File not found: "%s"', $fileInfo['file']));
 884:             }
 885:             if (is_int($name)) {
 886:                 $name = basename($fileInfo['file']);
 887:             }
 888:             if (!isset($fileInfo['mimetype'])) {
 889:                 $fileInfo['mimetype'] = 'application/octet-stream';
 890:             }
 891:             $attach[$name] = $fileInfo;
 892:         }
 893:         $this->_attachments = $attach;
 894:         return $this;
 895:     }
 896: 
 897: /**
 898:  * Add attachments
 899:  *
 900:  * @param mixed $attachments String with the filename or array with filenames
 901:  * @return CakeEmail $this
 902:  * @throws SocketException
 903:  */
 904:     public function addAttachments($attachments) {
 905:         $current = $this->_attachments;
 906:         $this->attachments($attachments);
 907:         $this->_attachments = array_merge($current, $this->_attachments);
 908:         return $this;
 909:     }
 910: 
 911: /**
 912:  * Get generated message (used by transport classes)
 913:  *
 914:  * @param mixed $type Use MESSAGE_* constants or null to return the full message as array
 915:  * @return mixed String if have type, array if type is null
 916:  */
 917:     public function message($type = null) {
 918:         switch ($type) {
 919:             case self::MESSAGE_HTML:
 920:                 return $this->_htmlMessage;
 921:             case self::MESSAGE_TEXT:
 922:                 return $this->_textMessage;
 923:         }
 924:         return $this->_message;
 925:     }
 926: 
 927: /**
 928:  * Configuration to use when send email
 929:  *
 930:  * @param mixed $config String with configuration name (from email.php), array with config or null to return current config
 931:  * @return mixed
 932:  */
 933:     public function config($config = null) {
 934:         if ($config === null) {
 935:             return $this->_config;
 936:         }
 937:         if (!is_array($config)) {
 938:             $config = (string)$config;
 939:         }
 940: 
 941:         $this->_applyConfig($config);
 942:         return $this;
 943:     }
 944: 
 945: /**
 946:  * Send an email using the specified content, template and layout
 947:  *
 948:  * @return array
 949:  * @throws SocketException
 950:  */
 951:     public function send($content = null) {
 952:         if (empty($this->_from)) {
 953:             throw new SocketException(__d('cake_dev', 'From is not specified.'));
 954:         }
 955:         if (empty($this->_to) && empty($this->_cc) && empty($this->_bcc)) {
 956:             throw new SocketException(__d('cake_dev', 'You need specify one destination on to, cc or bcc.'));
 957:         }
 958: 
 959:         if (is_array($content)) {
 960:             $content = implode("\n", $content) . "\n";
 961:         }
 962: 
 963:         $this->_textMessage = $this->_htmlMessage = '';
 964:         $this->_createBoundary();
 965:         $this->_message = $this->_render($this->_wrap($content));
 966: 
 967:         $contents = $this->transportClass()->send($this);
 968:         if (!empty($this->_config['log'])) {
 969:             $level = LOG_DEBUG;
 970:             if ($this->_config['log'] !== true) {
 971:                 $level = $this->_config['log'];
 972:             }
 973:             CakeLog::write($level, PHP_EOL . $contents['headers'] . PHP_EOL . $contents['message']);
 974:         }
 975:         return $contents;
 976:     }
 977: 
 978: /**
 979:  * Static method to fast create an instance of CakeEmail
 980:  *
 981:  * @param mixed $to Address to send (see CakeEmail::to()). If null, will try to use 'to' from transport config
 982:  * @param mixed $subject String of subject or null to use 'subject' from transport config
 983:  * @param mixed $message String with message or array with variables to be used in render
 984:  * @param mixed $transportConfig String to use config from EmailConfig or array with configs
 985:  * @param boolean $send Send the email or just return the instance pre-configured
 986:  * @return CakeEmail Instance of CakeEmail
 987:  * @throws SocketException
 988:  */
 989:     public static function deliver($to = null, $subject = null, $message = null, $transportConfig = 'fast', $send = true) {
 990:         $class = __CLASS__;
 991:         $instance = new $class($transportConfig);
 992:         if ($to !== null) {
 993:             $instance->to($to);
 994:         }
 995:         if ($subject !== null) {
 996:             $instance->subject($subject);
 997:         }
 998:         if (is_array($message)) {
 999:             $instance->viewVars($message);
1000:             $message = null;
1001:         } elseif ($message === null && array_key_exists('message', $config = $instance->config())) {
1002:             $message = $config['message'];
1003:         }
1004: 
1005:         if ($send === true) {
1006:             $instance->send($message);
1007:         }
1008: 
1009:         return $instance;
1010:     }
1011: 
1012: /**
1013:  * Apply the config to an instance
1014:  *
1015:  * @param CakeEmail $obj CakeEmail
1016:  * @param array $config
1017:  * @return void
1018:  */
1019:     protected function _applyConfig($config) {
1020:         if (is_string($config)) {
1021:             if (!class_exists('EmailConfig') && !config('email')) {
1022:                 throw new ConfigureException(__d('cake_dev', '%s not found.', APP . 'Config' . DS . 'email.php'));
1023:             }
1024:             $configs = new EmailConfig();
1025:             if (!isset($configs->{$config})) {
1026:                 throw new ConfigureException(__d('cake_dev', 'Unknown email configuration "%s".', $config));
1027:             }
1028:             $config = $configs->{$config};
1029:         }
1030:         $this->_config += $config;
1031:         if (!empty($config['charset'])) {
1032:             $this->charset = $config['charset'];
1033:         }
1034:         if (!empty($config['headerCharset'])) {
1035:             $this->headerCharset = $config['headerCharset'];
1036:         }
1037:         if (empty($this->headerCharset)) {
1038:             $this->headerCharset = $this->charset;
1039:         }
1040:         $simpleMethods = array(
1041:             'from', 'sender', 'to', 'replyTo', 'readReceipt', 'returnPath', 'cc', 'bcc',
1042:             'messageId', 'subject', 'viewRender', 'viewVars', 'attachments',
1043:             'transport', 'emailFormat'
1044:         );
1045:         foreach ($simpleMethods as $method) {
1046:             if (isset($config[$method])) {
1047:                 $this->$method($config[$method]);
1048:                 unset($config[$method]);
1049:             }
1050:         }
1051:         if (isset($config['headers'])) {
1052:             $this->setHeaders($config['headers']);
1053:             unset($config['headers']);
1054:         }
1055:         if (array_key_exists('template', $config)) {
1056:             $layout = false;
1057:             if (array_key_exists('layout', $config)) {
1058:                 $layout = $config['layout'];
1059:                 unset($config['layout']);
1060:             }
1061:             $this->template($config['template'], $layout);
1062:             unset($config['template']);
1063:         }
1064:         $this->transportClass()->config($config);
1065:     }
1066: 
1067: /**
1068:  * Reset all EmailComponent internal variables to be able to send out a new email.
1069:  *
1070:  * @return CakeEmail $this
1071:  */
1072:     public function reset() {
1073:         $this->_to = array();
1074:         $this->_from = array();
1075:         $this->_sender = array();
1076:         $this->_replyTo = array();
1077:         $this->_readReceipt = array();
1078:         $this->_returnPath = array();
1079:         $this->_cc = array();
1080:         $this->_bcc = array();
1081:         $this->_messageId = true;
1082:         $this->_subject = '';
1083:         $this->_headers = array();
1084:         $this->_layout = 'default';
1085:         $this->_template = '';
1086:         $this->_viewRender = 'View';
1087:         $this->_viewVars = array();
1088:         $this->_helpers = array('Html');
1089:         $this->_textMessage = '';
1090:         $this->_htmlMessage = '';
1091:         $this->_message = '';
1092:         $this->_emailFormat = 'text';
1093:         $this->_transportName = 'Mail';
1094:         $this->_transportClass = null;
1095:         $this->_attachments = array();
1096:         $this->_config = array();
1097:         return $this;
1098:     }
1099: 
1100: /**
1101:  * Encode the specified string using the current charset
1102:  *
1103:  * @param string $text String to encode
1104:  * @return string Encoded string
1105:  */
1106:     protected function _encode($text) {
1107:         $internalEncoding = function_exists('mb_internal_encoding');
1108:         if ($internalEncoding) {
1109:             $restore = mb_internal_encoding();
1110:             mb_internal_encoding($this->_appCharset);
1111:         }
1112:         if (strpos($text, ',') !== false) {
1113:             $text = '"' . $text . '"';
1114:         }
1115:         $return = mb_encode_mimeheader($text, $this->headerCharset, 'B');
1116:         if ($internalEncoding) {
1117:             mb_internal_encoding($restore);
1118:         }
1119:         return $return;
1120:     }
1121: 
1122: /**
1123:  * Translates a string for one charset to another if the App.encoding value
1124:  * differs and the mb_convert_encoding function exists
1125:  *
1126:  * @param string $text The text to be converted
1127:  * @param string $charset the target encoding
1128:  * @return string
1129:  */
1130:     protected function _encodeString($text, $charset) {
1131:         if ($this->_appCharset === $charset || !function_exists('mb_convert_encoding')) {
1132:             return $text;
1133:         }
1134:         return mb_convert_encoding($text, $charset, $this->_appCharset);
1135:     }
1136: 
1137: /**
1138:  * Wrap the message to follow the RFC 2822 - 2.1.1
1139:  *
1140:  * @param string $message Message to wrap
1141:  * @return array Wrapped message
1142:  */
1143:     protected function _wrap($message) {
1144:         $message = str_replace(array("\r\n", "\r"), "\n", $message);
1145:         $lines = explode("\n", $message);
1146:         $formatted = array();
1147: 
1148:         foreach ($lines as $line) {
1149:             if (empty($line)) {
1150:                 $formatted[] = '';
1151:                 continue;
1152:             }
1153:             if ($line[0] === '.') {
1154:                 $line = '.' . $line;
1155:             }
1156:             if (!preg_match('/\<[a-z]/i', $line)) {
1157:                 $formatted = array_merge($formatted, explode("\n", wordwrap($line, self::LINE_LENGTH_SHOULD, "\n")));
1158:                 continue;
1159:             }
1160: 
1161:             $tagOpen = false;
1162:             $tmpLine = $tag = '';
1163:             $tmpLineLength = 0;
1164:             for ($i = 0, $count = strlen($line); $i < $count; $i++) {
1165:                 $char = $line[$i];
1166:                 if ($tagOpen) {
1167:                     $tag .= $char;
1168:                     if ($char === '>') {
1169:                         $tagLength = strlen($tag);
1170:                         if ($tagLength + $tmpLineLength < self::LINE_LENGTH_SHOULD) {
1171:                             $tmpLine .= $tag;
1172:                             $tmpLineLength += $tagLength;
1173:                         } else {
1174:                             if ($tmpLineLength > 0) {
1175:                                 $formatted[] = trim($tmpLine);
1176:                                 $tmpLine = '';
1177:                                 $tmpLineLength = 0;
1178:                             }
1179:                             if ($tagLength > self::LINE_LENGTH_SHOULD) {
1180:                                 $formatted[] = $tag;
1181:                             } else {
1182:                                 $tmpLine = $tag;
1183:                                 $tmpLineLength = $tagLength;
1184:                             }
1185:                         }
1186:                         $tag = '';
1187:                         $tagOpen = false;
1188:                     }
1189:                     continue;
1190:                 }
1191:                 if ($char === '<') {
1192:                     $tagOpen = true;
1193:                     $tag = '<';
1194:                     continue;
1195:                 }
1196:                 if ($char === ' ' && $tmpLineLength >= self::LINE_LENGTH_SHOULD) {
1197:                     $formatted[] = $tmpLine;
1198:                     $tmpLineLength = 0;
1199:                     continue;
1200:                 }
1201:                 $tmpLine .= $char;
1202:                 $tmpLineLength++;
1203:                 if ($tmpLineLength === self::LINE_LENGTH_SHOULD) {
1204:                     $nextChar = $line[$i + 1];
1205:                     if ($nextChar === ' ' || $nextChar === '<') {
1206:                         $formatted[] = trim($tmpLine);
1207:                         $tmpLine = '';
1208:                         $tmpLineLength = 0;
1209:                         if ($nextChar === ' ') {
1210:                             $i++;
1211:                         }
1212:                     } else {
1213:                         $lastSpace = strrpos($tmpLine, ' ');
1214:                         if ($lastSpace === false) {
1215:                             continue;
1216:                         }
1217:                         $formatted[] = trim(substr($tmpLine, 0, $lastSpace));
1218:                         $tmpLine = substr($tmpLine, $lastSpace + 1);
1219: 
1220:                         $tmpLineLength = strlen($tmpLine);
1221:                     }
1222:                 }
1223:             }
1224:             if (!empty($tmpLine)) {
1225:                 $formatted[] = $tmpLine;
1226:             }
1227:         }
1228:         $formatted[] = '';
1229:         return $formatted;
1230:     }
1231: 
1232: /**
1233:  * Create unique boundary identifier
1234:  *
1235:  * @return void
1236:  */
1237:     protected function _createBoundary() {
1238:         if (!empty($this->_attachments) || $this->_emailFormat === 'both') {
1239:             $this->_boundary = md5(uniqid(time()));
1240:         }
1241:     }
1242: 
1243: /**
1244:  * Attach non-embedded files by adding file contents inside boundaries.
1245:  *
1246:  * @param string $boundary Boundary to use. If null, will default to $this->_boundary 
1247:  * @return array An array of lines to add to the message
1248:  */
1249:     protected function _attachFiles($boundary = null) {
1250:         if ($boundary === null) {
1251:             $boundary = $this->_boundary;
1252:         }
1253: 
1254:         $msg = array();
1255:         foreach ($this->_attachments as $filename => $fileInfo) {
1256:             if (!empty($fileInfo['contentId'])) {
1257:                 continue;
1258:             }
1259:             $data = $this->_readFile($fileInfo['file']);
1260: 
1261:             $msg[] = '--' . $boundary;
1262:             $msg[] = 'Content-Type: ' . $fileInfo['mimetype'];
1263:             $msg[] = 'Content-Transfer-Encoding: base64';
1264:             $msg[] = 'Content-Disposition: attachment; filename="' . $filename . '"';
1265:             $msg[] = '';
1266:             $msg[] = $data;
1267:             $msg[] = '';
1268:         }
1269:         return $msg;
1270:     }
1271: 
1272: /**
1273:  * Read the file contents and return a base64 version of the file contents.
1274:  *
1275:  * @param string $file The file to read.
1276:  * @return string File contents in base64 encoding
1277:  */
1278:     protected function _readFile($file) {
1279:         $handle = fopen($file, 'rb');
1280:         $data = fread($handle, filesize($file));
1281:         $data = chunk_split(base64_encode($data)) ;
1282:         fclose($handle);
1283:         return $data;
1284:     }
1285: 
1286: /**
1287:  * Attach inline/embedded files to the message.
1288:  *
1289:  * @param string $boundary Boundary to use. If null, will default to $this->_boundary 
1290:  * @return array An array of lines to add to the message
1291:  */
1292:     protected function _attachInlineFiles($boundary = null) {
1293:         if ($boundary === null) {
1294:             $boundary = $this->_boundary;
1295:         }
1296: 
1297:         $msg = array();
1298:         foreach ($this->_attachments as $filename => $fileInfo) {
1299:             if (empty($fileInfo['contentId'])) {
1300:                 continue;
1301:             }
1302:             $data = $this->_readFile($fileInfo['file']);
1303: 
1304:             $msg[] = '--' . $boundary;
1305:             $msg[] = 'Content-Type: ' . $fileInfo['mimetype'];
1306:             $msg[] = 'Content-Transfer-Encoding: base64';
1307:             $msg[] = 'Content-ID: <' . $fileInfo['contentId'] . '>';
1308:             $msg[] = 'Content-Disposition: inline; filename="' . $filename . '"';
1309:             $msg[] = '';
1310:             $msg[] = $data;
1311:             $msg[] = '';
1312:         }
1313:         return $msg;
1314:     }
1315: 
1316: /**
1317:  * Render the body of the email.
1318:  *
1319:  * @param string $content Content to render
1320:  * @return array Email body ready to be sent
1321:  */
1322:     protected function _render($content) {
1323:         $content = implode("\n", $content);
1324:         $rendered = $this->_renderTemplates($content);
1325: 
1326:         $msg = array();
1327: 
1328:         $contentIds = array_filter((array)Set::classicExtract($this->_attachments, '{s}.contentId'));
1329:         $hasInlineAttachments = count($contentIds) > 0;
1330:         $hasAttachments = !empty($this->_attachments);
1331:         $hasMultipleTypes = count($rendered) > 1;
1332: 
1333:         $boundary = $relBoundary = $textBoundary = $this->_boundary;
1334: 
1335:         if ($hasInlineAttachments) {
1336:             $msg[] = '--' . $boundary;
1337:             $msg[] = 'Content-Type: multipart/related; boundary="rel-' . $boundary . '"';
1338:             $msg[] = '';
1339:             $relBoundary = $textBoundary = 'rel-' . $boundary;
1340:         }
1341: 
1342:         if ($hasMultipleTypes) {
1343:             $msg[] = '--' . $relBoundary;
1344:             $msg[] = 'Content-Type: multipart/alternative; boundary="alt-' . $boundary . '"';
1345:             $msg[] = '';
1346:             $textBoundary = 'alt-' . $boundary;
1347:         }
1348: 
1349:         if (isset($rendered['text'])) {
1350:             if ($textBoundary !== $boundary || $hasAttachments) {
1351:                 $msg[] = '--' . $textBoundary;
1352:                 $msg[] = 'Content-Type: text/plain; charset=' . $this->charset;
1353:                 $msg[] = 'Content-Transfer-Encoding: ' . $this->_getContentTransferEncoding();
1354:                 $msg[] = '';
1355:             }
1356:             $this->_textMessage = $rendered['text'];
1357:             $content = explode("\n", $this->_textMessage);
1358:             $msg = array_merge($msg, $content);
1359:             $msg[] = '';
1360:         }
1361:     
1362:         if (isset($rendered['html'])) {
1363:             if ($textBoundary !== $boundary || $hasAttachments) {
1364:                 $msg[] = '--' . $textBoundary;
1365:                 $msg[] = 'Content-Type: text/html; charset=' . $this->charset;
1366:                 $msg[] = 'Content-Transfer-Encoding: ' . $this->_getContentTransferEncoding();
1367:                 $msg[] = '';
1368:             }
1369:             $this->_htmlMessage = $rendered['html'];
1370:             $content = explode("\n", $this->_htmlMessage);
1371:             $msg = array_merge($msg, $content);
1372:             $msg[] = '';
1373:         }
1374: 
1375:         if ($hasMultipleTypes) {
1376:             $msg[] = '--' . $textBoundary . '--';
1377:             $msg[] = '';
1378:         }
1379: 
1380:         if ($hasInlineAttachments) {
1381:             $attachments = $this->_attachInlineFiles($relBoundary);
1382:             $msg = array_merge($msg, $attachments);
1383:             $msg[] = '';
1384:             $msg[] = '--' . $relBoundary . '--';
1385:             $msg[] = '';
1386:         }
1387: 
1388:         if ($hasAttachments) {
1389:             $attachments = $this->_attachFiles($boundary);
1390:             $msg = array_merge($msg, $attachments);
1391:         }
1392:         if ($hasAttachments || $hasMultipleTypes) {
1393:             $msg[] = '';
1394:             $msg[] = '--' . $boundary . '--';
1395:             $msg[] = '';
1396:         }
1397:         return $msg;
1398:     }
1399: 
1400: /**
1401:  * Gets the text body types that are in this email message
1402:  *
1403:  * @return array Array of types.  Valid types are 'text' and 'html'
1404:  */
1405:     protected function _getTypes() {
1406:         $types = array($this->_emailFormat);
1407:         if ($this->_emailFormat == 'both') {
1408:             $types = array('html', 'text');
1409:         }
1410:         return $types;
1411:     }
1412: 
1413: /**
1414:  * Build and set all the view properties needed to render the templated emails.
1415:  * If there is no template set, the $content will be returned in a hash
1416:  * of the text content types for the email.
1417:  *
1418:  * @param string $content The content passed in from send() in most cases.
1419:  * @return array The rendered content with html and text keys.
1420:  */
1421:     protected function _renderTemplates($content) {
1422:         $types = $this->_getTypes();
1423:         $rendered = array();
1424:         if (empty($this->_template)) {
1425:             foreach ($types as $type) {
1426:                 $rendered[$type] = $this->_encodeString($content, $this->charset);
1427:             }
1428:             return $rendered;
1429:         }
1430:         $viewClass = $this->_viewRender;
1431:         if ($viewClass !== 'View') {
1432:             list($plugin, $viewClass) = pluginSplit($viewClass, true);
1433:             $viewClass .= 'View';
1434:             App::uses($viewClass, $plugin . 'View');
1435:         }
1436: 
1437:         $View = new $viewClass(null);
1438:         $View->viewVars = $this->_viewVars;
1439:         $View->helpers = $this->_helpers;
1440: 
1441:         list($templatePlugin, $template) = pluginSplit($this->_template);
1442:         list($layoutPlugin, $layout) = pluginSplit($this->_layout);
1443:         if ($templatePlugin) {
1444:             $View->plugin = $templatePlugin;
1445:         } elseif ($layoutPlugin) {
1446:             $View->plugin = $layoutPlugin;
1447:         }
1448: 
1449:         foreach ($types as $type) {
1450:             $View->set('content', $content);
1451:             $View->hasRendered = false;
1452:             $View->viewPath = $View->layoutPath = 'Emails' . DS . $type;
1453:     
1454:             $render = $View->render($template, $layout);
1455:             $render = str_replace(array("\r\n", "\r"), "\n", $render);
1456:             $rendered[$type] = $this->_encodeString($render, $this->charset);
1457:         }
1458:         return $rendered;
1459:     }
1460: 
1461: /**
1462:  * Return the Content-Transfer Encoding value based on the set charset
1463:  *
1464:  * @return void
1465:  */
1466:     protected function _getContentTransferEncoding() {
1467:         $charset = strtoupper($this->charset);
1468:         if (in_array($charset, $this->_charset8bit)) {
1469:             return '8bit';
1470:         }
1471:         return '7bit';
1472:     }
1473: }
1474: 
OpenHub
Rackspace
Rackspace
  • Business Solutions
  • Showcase
  • Documentation
  • Book
  • API
  • Videos
  • Reporting Security Issues
  • Privacy Policy
  • Logos & Trademarks
  • Community
  • Get Involved
  • Issues (GitHub)
  • Bakery
  • Featured Resources
  • Training
  • Meetups
  • My CakePHP
  • CakeFest
  • Newsletter
  • Linkedin
  • YouTube
  • Facebook
  • Twitter
  • Mastodon
  • Help & Support
  • Forum
  • Stack Overflow
  • Slack
  • Paid Support

Generated using CakePHP API Docs