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.1 API

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