├── CHANGELOG.md ├── LICENSE ├── README.md ├── composer.json ├── config ├── email.php └── index.html ├── helpers ├── MY_email_helper.php └── index.html └── libraries ├── MY_Email.php └── index.html /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 1.5.0 - 25-AUG-2022 2 | ------------------- 3 | 4 | * Requires PHP >= 7.3.0. 5 | * XOAUTH2 authentication has been added for enail accounts hosted by Google, Yahoo, Microsoft. 6 | 7 | 8 | 1.4.7 - 27-FEB-2021 9 | ------------------- 10 | 11 | * Silent detection about ini_get('mbstring.func_overload') has been added. 12 | 13 | 14 | 1.4.6 - 29-NOV-2020 15 | ------------------- 16 | 17 | * Switching to PHPMailer ^6.2.0 which is also PHP 8 compatible. 18 | 19 | 20 | 1.4.5 - 25-JUN-2020 21 | ------------------- 22 | 23 | * README.md: Poser badges have been added. 24 | 25 | 26 | 1.4.4 - 07-JUN-2020 27 | ------------------- 28 | 29 | * Corrections within README.md and CHANGELOG.md. 30 | 31 | 32 | 1.4.3 - 07-JUN-2020 33 | ------------------- 34 | 35 | * CHANGELOG.md file has been added. 36 | 37 | 38 | 1.4.2 - 06-JUN-2020 39 | ------------------- 40 | 41 | * New installation instructions have been prepared. 42 | 43 | 44 | 1.4.1 - 06-JUN-2020 45 | ------------------- 46 | 47 | * Initial Composer-managed package. Requirements: CodeIgniter 3.1.x, PHP >= 5.5.0, Composer enabled, PHPMailer >= 6.1.6. 48 | * For supporting CodeIgniter 2.x and CodeIgniter 3.0.x a manual installation of an older version of this 49 | library is needed, see https://github.com/ivantcholakov/codeigniter-phpmailer/tree/1.3-stable 50 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2012-2022 Ivan Tcholakov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Latest Stable Version](https://poser.pugx.org/ivantcholakov/codeigniter-phpmailer/v)](//packagist.org/packages/ivantcholakov/codeigniter-phpmailer) 2 | [![Total Downloads](https://poser.pugx.org/ivantcholakov/codeigniter-phpmailer/downloads)](//packagist.org/packages/ivantcholakov/codeigniter-phpmailer) 3 | [![Latest Unstable Version](https://poser.pugx.org/ivantcholakov/codeigniter-phpmailer/v/unstable)](//packagist.org/packages/ivantcholakov/codeigniter-phpmailer) 4 | [![License](https://poser.pugx.org/ivantcholakov/codeigniter-phpmailer/license)](//packagist.org/packages/ivantcholakov/codeigniter-phpmailer) 5 | 6 | A CodeIgniter compatible email-library powered by PHPMailer 7 | =========================================================== 8 | 9 | Version: 1.5.0 10 | Author: Ivan Tcholakov , 2012-2022. 11 | License: The MIT License (MIT), http://opensource.org/licenses/MIT 12 | 13 | This library is compatible with CodeIgniter 3.1.x and PHP >= 7.3.0. 14 | 15 | Tested on CodeIgniter 3.1.13 (March 3rd, 2022) and PHPMailer Version 6.6.4 (August 22nd, 2022). 16 | 17 | Links 18 | ----- 19 | 20 | Package: https://packagist.org/packages/ivantcholakov/codeigniter-phpmailer 21 | 22 | PHPMailer: https://github.com/PHPMailer/PHPMailer 23 | 24 | Installation 25 | ------------ 26 | 27 | Enable Composer to be used by CodeIgniter. Check this page from its documentation: 28 | https://www.codeigniter.com/userguide3/general/autoloader.html . 29 | You need to see or decide when your vendor/ directory is (to be) and within the 30 | CodeIgniter's configuration file application/config/config.php you need to set the 31 | configuration option $config['composer_autoload'] accordingly. For the typical location 32 | application/vendor/ the configuration setting would look like this: 33 | 34 | ```php 35 | $config['composer_autoload'] = APPPATH.'vendor/autoload.php'; 36 | ``` 37 | 38 | Within application/config/constants.php add the following lines: 39 | 40 | ```php 41 | // Path to Composer's vendor/ directory, it should end with a trailing slash. 42 | defined('VENDORPATH') OR define('VENDORPATH', rtrim(str_replace('\\', '/', realpath(dirname(APPPATH.'vendor/autoload.php'))), '/').'/'); 43 | ``` 44 | 45 | It is assumed that Composer's vendor/ directory is placed under CodeIgniter's 46 | application/ directory. Otherwise correct the setting so VENDORPATH to point correctly. 47 | 48 | If PHPMailer was previously installed through Composer, uninstall it temporarily: 49 | 50 | ``` 51 | composer remove PHPMailer/PHPMailer 52 | ``` 53 | 54 | Now install this library's package, it will install a correct version of PHPMailer too: 55 | 56 | ``` 57 | composer require ivantcholakov/codeigniter-phpmailer 58 | ``` 59 | 60 | Create a file application/helpers/MY_email_helper.php with the following content: 61 | 62 | ```php 63 | load->library('email'); 171 | 172 | $subject = 'This is a test'; 173 | $message = ' 174 |

This message has been sent for testing purposes.

175 | 176 | 177 |

178 | '; 179 | 180 | // Get full html: 181 | $body = ' 182 | 183 | 184 | 185 | ' . html_escape($subject) . ' 186 | 192 | 193 | 194 | ' . $message . ' 195 | 196 | '; 197 | // Also, for getting full html you may use the following internal method: 198 | //$body = $this->email->full_html($subject, $message); 199 | 200 | // Attaching the logo first. 201 | $file_logo = FCPATH.'apple-touch-icon-precomposed.png'; // Change the path accordingly. 202 | // The last additional parameter is set to true in order 203 | // the image (logo) to appear inline, within the message text: 204 | $this->email->attach($file_logo, 'inline', null, '', true); 205 | $cid_logo = $this->email->get_attachment_cid($file_logo); 206 | $body = str_replace('cid:logo_src', 'cid:'.$cid_logo, $body); 207 | // End attaching the logo. 208 | 209 | $result = $this->email 210 | ->from('yourusername@gmail.com') 211 | ->reply_to('yoursecondemail@somedomain.com') // Optional, an account where a human being reads. 212 | ->to('therecipient@otherdomain.com') 213 | ->subject($subject) 214 | ->message($body) 215 | ->send(); 216 | 217 | var_dump($result); 218 | echo '
'; 219 | echo $this->email->print_debugger(); 220 | 221 | exit; 222 | ``` 223 | 224 | Load the corresponding page, executte this code. Check whether an email has been sent. Read the error message, 225 | if any, and make corrections in your settings. 226 | 227 | Note, that most of the SMTP servers require "from" address of the message to be the same as the address within 228 | $config['smtp_user'] setting. 229 | 230 | At the end remove this test. 231 | 232 | The API of this library is the same as the original Email API. Read the CodeIgniter's manual about 233 | [Email Class](https://www.codeigniter.com/userguide3/libraries/email.html). 234 | 235 | For supporting CodeIgniter 2.x and CodeIgniter 3.0.x a manual installation of an older version of this 236 | library is needed, see https://github.com/ivantcholakov/codeigniter-phpmailer/tree/1.3-stable 237 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ivantcholakov/codeigniter-phpmailer", 3 | "description": "A CodeIgniter 3 compatible email-library powered by PHPMailer.", 4 | "keywords": ["php", "codeigniter", "phpmailer"], 5 | "homepage": "https://github.com/ivantcholakov/codeigniter-phpmailer", 6 | "type": "library", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "Ivan Tcholakov", 11 | "email": "ivantcholakov@gmail.com", 12 | "homepage": "https://github.com/ivantcholakov" 13 | } 14 | ], 15 | "require": { 16 | "php": ">=7.3.0", 17 | "phpmailer/phpmailer": "^6.6.4", 18 | "league/oauth2-google": "^4.0.0", 19 | "hayageek/oauth2-yahoo": "^2.0.5", 20 | "stevenmaguire/oauth2-microsoft": "^2.2.0" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /config/email.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /helpers/MY_email_helper.php: -------------------------------------------------------------------------------- 1 | 8.0, PHP >= 5.3.2, 5.2.14; 12 | * * `pcre` Use old PCRE implementation; 13 | * * `php` Use PHP built-in FILTER_VALIDATE_EMAIL; 14 | * * `html5` Use the pattern given by the HTML5 spec for 'email' type form input elements. 15 | * * `noregex` Don't use a regex: super fast, really dumb. 16 | * Alternatively you may pass in a callable to inject your own validator, for example: 17 | * PHPMailer::validateAddress('user@example.com', function($address) { 18 | * return (strpos($address, '@') !== false); 19 | * }); 20 | * You can also set the PHPMailer::$validator static to a callable, allowing built-in methods to use your validator. 21 | * @return boolean 22 | * @static 23 | * @access public 24 | */ 25 | // Modified by Ivan Tcholakov, 06-JAN-2019. 26 | //public static function validateAddress($address, $patternselect = null) 27 | //{ 28 | // if (is_null($patternselect)) { 29 | // $patternselect = self::$validator; 30 | // } 31 | // if (is_callable($patternselect)) { 32 | // return call_user_func($patternselect, $address); 33 | // } 34 | // //Reject line breaks in addresses; it's valid RFC5322, but not RFC5321 35 | // if (strpos($address, "\n") !== false or strpos($address, "\r") !== false) { 36 | // return false; 37 | // } 38 | function valid_email($address) { 39 | $patternselect = 'auto'; 40 | if (is_php('7.3')) { 41 | $patternselect = 'php'; 42 | } 43 | //Reject line breaks in addresses; it's valid RFC5322, but not RFC5321 44 | if (strpos($address, "\n") !== false or strpos($address, "\r") !== false) { 45 | return false; 46 | } 47 | // Added by Ivan Tcholakov, 17-OCT-2015. 48 | if (function_exists('idn_to_ascii') && defined('INTL_IDNA_VARIANT_UTS46') && $atpos = strpos($address, '@')) { 49 | $address = substr($address, 0, ++$atpos).idn_to_ascii(substr($address, $atpos), 0, INTL_IDNA_VARIANT_UTS46); 50 | } 51 | // 52 | // 53 | if (!$patternselect or $patternselect == 'auto') { 54 | //Check this constant first so it works when extension_loaded() is disabled by safe mode 55 | //Constant was added in PHP 5.2.4 56 | if (defined('PCRE_VERSION')) { 57 | //This pattern can get stuck in a recursive loop in PCRE <= 8.0.2 58 | if (version_compare(PCRE_VERSION, '8.0.3') >= 0) { 59 | $patternselect = 'pcre8'; 60 | } else { 61 | $patternselect = 'pcre'; 62 | } 63 | } elseif (function_exists('extension_loaded') and extension_loaded('pcre')) { 64 | //Fall back to older PCRE 65 | $patternselect = 'pcre'; 66 | } else { 67 | //Filter_var appeared in PHP 5.2.0 and does not require the PCRE extension 68 | if (version_compare(PHP_VERSION, '5.2.0') >= 0) { 69 | $patternselect = 'php'; 70 | } else { 71 | $patternselect = 'noregex'; 72 | } 73 | } 74 | } 75 | switch ($patternselect) { 76 | case 'pcre8': 77 | /** 78 | * Uses the same RFC5322 regex on which FILTER_VALIDATE_EMAIL is based, but allows dotless domains. 79 | * @link http://squiloople.com/2009/12/20/email-address-validation/ 80 | * @copyright 2009-2010 Michael Rushton 81 | * Feel free to use and redistribute this code. But please keep this copyright notice. 82 | */ 83 | return (boolean)preg_match( 84 | '/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)' . 85 | '((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)' . 86 | '(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)' . 87 | '([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*' . 88 | '(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)' . 89 | '(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}' . 90 | '|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:' . 91 | '|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}' . 92 | '|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD', 93 | $address 94 | ); 95 | case 'pcre': 96 | //An older regex that doesn't need a recent PCRE 97 | return (boolean)preg_match( 98 | '/^(?!(?>"?(?>\\\[ -~]|[^"])"?){255,})(?!(?>"?(?>\\\[ -~]|[^"])"?){65,}@)(?>' . 99 | '[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*")' . 100 | '(?>\.(?>[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*"))*' . 101 | '@(?>(?![a-z0-9-]{64,})(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>\.(?![a-z0-9-]{64,})' . 102 | '(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?)){0,126}|\[(?:(?>IPv6:(?>(?>[a-f0-9]{1,4})(?>:' . 103 | '[a-f0-9]{1,4}){7}|(?!(?:.*[a-f0-9][:\]]){8,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?' . 104 | '::(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?))|(?>(?>IPv6:(?>[a-f0-9]{1,4}(?>:' . 105 | '[a-f0-9]{1,4}){5}:|(?!(?:.*[a-f0-9]:){6,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4})?' . 106 | '::(?>(?:[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4}):)?))?(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}' . 107 | '|[1-9]?[0-9])(?>\.(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}))\])$/isD', 108 | $address 109 | ); 110 | case 'html5': 111 | /** 112 | * This is the pattern used in the HTML5 spec for validation of 'email' type form input elements. 113 | * @link http://www.whatwg.org/specs/web-apps/current-work/#e-mail-state-(type=email) 114 | */ 115 | return (boolean)preg_match( 116 | '/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}' . 117 | '[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/sD', 118 | $address 119 | ); 120 | case 'noregex': 121 | //No PCRE! Do something _very_ approximate! 122 | //Check the address is 3 chars or longer and contains an @ that's not the first or last char 123 | return (strlen($address) >= 3 124 | and strpos($address, '@') >= 1 125 | and strpos($address, '@') != strlen($address) - 1); 126 | case 'php': 127 | default: 128 | return (boolean)filter_var($address, FILTER_VALIDATE_EMAIL); 129 | } 130 | } 131 | 132 | } 133 | 134 | if (!function_exists('name_email_format')) { 135 | 136 | function name_email_format($name, $email) { 137 | return $name.' <'.$email.'>'; 138 | } 139 | 140 | } 141 | -------------------------------------------------------------------------------- /helpers/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /libraries/MY_Email.php: -------------------------------------------------------------------------------- 1 | , 2012-2022. 7 | * @license The MIT License (MIT), http://opensource.org/licenses/MIT 8 | * @link https://github.com/ivantcholakov/codeigniter-phpmailer 9 | * 10 | * Tested on CodeIgniter 3.1.13 (March 3rd, 2022) and 11 | * PHPMailer Version 6.6.4 (August 22nd, 2022). 12 | */ 13 | 14 | class MY_Email extends CI_Email { 15 | 16 | public $phpmailer; // This property has been made public for testing purposes. 17 | 18 | protected static $default_properties = array( 19 | 'useragent' => 'CodeIgniter', 20 | 'mailpath' => '/usr/sbin/sendmail', 21 | 'protocol' => 'mail', 22 | 'smtp_host' => '', 23 | 'smtp_auth' => NULL, 24 | 'smtp_user' => '', 25 | 'smtp_pass' => '', 26 | 'smtp_port' => 25, 27 | 'smtp_timeout' => 5, 28 | 'smtp_keepalive' => FALSE, 29 | 'smtp_crypto' => '', 30 | 'wordwrap' => TRUE, 31 | 'wrapchars' => 76, 32 | 'mailtype' => 'text', 33 | 'charset' => 'UTF-8', 34 | 'multipart' => 'mixed', 35 | 'alt_message' => '', 36 | 'validate' => FALSE, 37 | 'priority' => 3, 38 | 'newline' => "\n", 39 | 'crlf' => "\n", 40 | 'dsn' => FALSE, 41 | 'send_multipart' => TRUE, 42 | 'bcc_batch_mode' => FALSE, 43 | 'bcc_batch_size' => 200, 44 | 'debug_output' => '', 45 | 'smtp_debug' => 0, 46 | 'encoding' => '8bit', 47 | 'smtp_auto_tls' => true, 48 | 'smtp_conn_options' => array(), 49 | 'oauth_type' => '', 50 | 'oauth_instance' => null, 51 | 'oauth_user_email' => '', 52 | 'oauth_client_id' => '', 53 | 'oauth_client_secret' => '', 54 | 'oauth_refresh_token' => '', 55 | 'dkim_domain' => '', 56 | 'dkim_private' => '', 57 | 'dkim_private_string' => '', 58 | 'dkim_selector' => '', 59 | 'dkim_passphrase' => '', 60 | 'dkim_identity' => '', 61 | ); 62 | 63 | protected $properties = array(); 64 | 65 | protected $mailer_engine = 'codeigniter'; 66 | protected $CI; 67 | 68 | protected static $protocols = array('mail', 'sendmail', 'smtp'); 69 | protected static $mailtypes = array('html', 'text'); 70 | protected static $encodings_ci = array('8bit', '7bit'); 71 | protected static $encodings_phpmailer = array('8bit', '7bit', 'binary', 'base64', 'quoted-printable'); 72 | 73 | 74 | // The Constructor --------------------------------------------------------- 75 | 76 | public function __construct(array $config = array()) { 77 | 78 | $this->CI = get_instance(); 79 | $this->CI->load->helper('email'); 80 | $this->CI->load->helper('html'); 81 | 82 | isset(self::$func_overload) OR self::$func_overload = (defined('MB_OVERLOAD_STRING') && ((int) @ini_get('mbstring.func_overload') & MB_OVERLOAD_STRING)); 83 | 84 | // Set the default property 'debug_output' by using CLI autodetection. 85 | self::$default_properties['debug_output'] = (strpos(PHP_SAPI, 'cli') !== false OR defined('STDIN')) ? 'echo' : 'html'; 86 | 87 | // Wipe out certain properties that are declared within the parent class. 88 | // These properties would be accessed by magic. 89 | foreach (array_keys(self::$default_properties) as $name) { 90 | 91 | if (property_exists($this, $name)) { 92 | unset($this->{$name}); 93 | } 94 | } 95 | 96 | $this->properties = self::$default_properties; 97 | $this->refresh_properties(); 98 | 99 | $this->_safe_mode = (!is_php('5.4') && ini_get('safe_mode')); 100 | 101 | if (!isset($config['charset'])) { 102 | $config['charset'] = config_item('charset'); 103 | } 104 | 105 | $this->initialize($config); 106 | 107 | log_message('info', 'Email Class Initialized (Engine: '.$this->mailer_engine.')'); 108 | } 109 | 110 | // Triggers the setter functions to do their job. 111 | protected function refresh_properties() { 112 | 113 | foreach (array_keys(self::$default_properties) as $name) { 114 | $this->{$name} = $this->{$name}; 115 | } 116 | } 117 | 118 | 119 | // The Destructor ---------------------------------------------------------- 120 | 121 | public function __destruct() { 122 | 123 | if (is_callable('parent::__destruct')) { 124 | parent::__destruct(); 125 | } 126 | } 127 | 128 | 129 | // Magic ------------------------------------------------------------------- 130 | 131 | function __set($name, $value) { 132 | 133 | $method = 'set_'.$name; 134 | 135 | if (is_callable(array($this, $method))) { 136 | $this->$method($value); 137 | } else { 138 | $this->properties[$name] = $value; 139 | } 140 | } 141 | 142 | function __get($name) { 143 | 144 | if (array_key_exists($name, $this->properties)) { 145 | return $this->properties[$name]; 146 | } else { 147 | throw new \OutOfBoundsException('The property '.$name.' does not exists.'); 148 | } 149 | } 150 | 151 | public function __isset($name) { 152 | 153 | return isset($this->properties[$name]); 154 | } 155 | 156 | public function __unset($name) { 157 | 158 | $this->$name = null; 159 | 160 | if (array_key_exists($name, $this->properties)) { 161 | unset($this->properties[$name]); 162 | } else { 163 | unset($this->$name); 164 | } 165 | } 166 | 167 | 168 | // Keep the API Fluent ----------------------------------------------------- 169 | 170 | /** 171 | * An empty method that keeps chaining, the parameter does the desired operation as a side-effect. 172 | * 173 | * @param mixed $expression A (conditional) expression that is to be executed. 174 | * @return object Returns a reference to the created library instance. 175 | */ 176 | public function that($expression = NULL) { 177 | 178 | return $this; 179 | } 180 | 181 | 182 | // Initialization & Clearing ----------------------------------------------- 183 | 184 | public function initialize(array $config = array()) { 185 | 186 | foreach ($config as $key => $value) { 187 | $this->{$key} = $value; 188 | } 189 | 190 | $this->clear(); 191 | 192 | return $this; 193 | } 194 | 195 | public function clear($clear_attachments = false) { 196 | 197 | $clear_attachments = !empty($clear_attachments); 198 | 199 | parent::clear($clear_attachments); 200 | 201 | if ($this->mailer_engine == 'phpmailer') { 202 | 203 | $this->phpmailer->clearAllRecipients(); 204 | $this->phpmailer->clearReplyTos(); 205 | if ($clear_attachments) { 206 | $this->phpmailer->clearAttachments(); 207 | } 208 | 209 | $this->phpmailer->clearCustomHeaders(); 210 | 211 | $this->phpmailer->Subject = ''; 212 | $this->phpmailer->Body = ''; 213 | $this->phpmailer->AltBody = ''; 214 | } 215 | 216 | return $this; 217 | } 218 | 219 | 220 | // Prepare & Send a Message ------------------------------------------------ 221 | 222 | public function from($from, $name = '', $return_path = NULL) { 223 | 224 | $from = (string) $from; 225 | $name = (string) $name; 226 | $return_path = (string) $return_path; 227 | 228 | if ($this->mailer_engine == 'phpmailer') { 229 | 230 | if (preg_match( '/\<(.*)\>/', $from, $match)) { 231 | $from = $match['1']; 232 | } 233 | 234 | if ($this->validate) { 235 | 236 | $this->validate_email($this->_str_to_array($from)); 237 | 238 | if ($return_path) { 239 | $this->validate_email($this->_str_to_array($return_path)); 240 | } 241 | } 242 | 243 | $this->phpmailer->setFrom($from, $name, 0); 244 | 245 | if (!$return_path) { 246 | $return_path = $from; 247 | } 248 | 249 | $this->phpmailer->Sender = $return_path; 250 | 251 | } else { 252 | 253 | parent::from($from, $name, $return_path); 254 | } 255 | 256 | return $this; 257 | } 258 | 259 | public function reply_to($replyto, $name = '') { 260 | 261 | $replyto = (string) $replyto; 262 | $name = (string) $name; 263 | 264 | if ($this->mailer_engine == 'phpmailer') { 265 | 266 | if (preg_match( '/\<(.*)\>/', $replyto, $match)) { 267 | $replyto = $match['1']; 268 | } 269 | 270 | if ($this->validate) { 271 | $this->validate_email($this->_str_to_array($replyto)); 272 | } 273 | 274 | if ($name == '') { 275 | $name = $replyto; 276 | } 277 | 278 | $this->phpmailer->addReplyTo($replyto, $name); 279 | 280 | $this->_replyto_flag = TRUE; 281 | 282 | } else { 283 | 284 | parent::reply_to($replyto, $name); 285 | } 286 | 287 | return $this; 288 | } 289 | 290 | public function to($to) { 291 | 292 | if ($this->mailer_engine == 'phpmailer') { 293 | 294 | $to = $this->_str_to_array($to); 295 | $names = $this->_extract_name($to); 296 | $to = $this->clean_email($to); 297 | 298 | if ($this->validate) { 299 | $this->validate_email($to); 300 | } 301 | 302 | $i = 0; 303 | 304 | foreach ($to as $address) { 305 | 306 | $this->phpmailer->addAddress($address, $names[$i]); 307 | 308 | $i++; 309 | } 310 | 311 | } else { 312 | 313 | parent::to($to); 314 | } 315 | 316 | return $this; 317 | } 318 | 319 | public function cc($cc) { 320 | 321 | if ($this->mailer_engine == 'phpmailer') { 322 | 323 | $cc = $this->_str_to_array($cc); 324 | $names = $this->_extract_name($cc); 325 | $cc = $this->clean_email($cc); 326 | 327 | if ($this->validate) { 328 | $this->validate_email($cc); 329 | } 330 | 331 | $i = 0; 332 | 333 | foreach ($cc as $address) { 334 | 335 | $this->phpmailer->addCC($address, $names[$i]); 336 | 337 | $i++; 338 | } 339 | 340 | } else { 341 | 342 | parent::cc($cc); 343 | } 344 | 345 | return $this; 346 | } 347 | 348 | public function bcc($bcc, $limit = '') { 349 | 350 | if ($this->mailer_engine == 'phpmailer') { 351 | 352 | $bcc = $this->_str_to_array($bcc); 353 | $names = $this->_extract_name($bcc); 354 | $bcc = $this->clean_email($bcc); 355 | 356 | if ($this->validate) { 357 | $this->validate_email($bcc); 358 | } 359 | 360 | $i = 0; 361 | 362 | foreach ($bcc as $address) { 363 | 364 | $this->phpmailer->addBCC($address, $names[$i]); 365 | 366 | $i++; 367 | } 368 | 369 | } else { 370 | 371 | parent::bcc($bcc, $limit); 372 | } 373 | 374 | return $this; 375 | } 376 | 377 | public function subject($subject) { 378 | 379 | $subject = (string) $subject; 380 | 381 | if ($this->mailer_engine == 'phpmailer') { 382 | 383 | // Modified by Ivan Tcholakov, 01-AUG-2015. 384 | // See https://github.com/ivantcholakov/codeigniter-phpmailer/issues/8 385 | // This change probably is not needed, done anyway. 386 | //$this->phpmailer->Subject = $subject; 387 | $this->phpmailer->Subject = str_replace(array('{unwrap}', '{/unwrap}'), '', $subject); 388 | // 389 | 390 | } else { 391 | 392 | parent::subject($subject); 393 | } 394 | 395 | return $this; 396 | } 397 | 398 | public function message($body) { 399 | 400 | $body = (string) $body; 401 | 402 | if ($this->mailer_engine == 'phpmailer') { 403 | 404 | // Modified by Ivan Tcholakov, 01-AUG-2015. 405 | // See https://github.com/ivantcholakov/codeigniter-phpmailer/issues/8 406 | //$this->phpmailer->Body = $body; 407 | $this->phpmailer->Body = str_replace(array('{unwrap}', '{/unwrap}'), '', $body); 408 | // 409 | } 410 | 411 | parent::message($body); 412 | 413 | return $this; 414 | } 415 | 416 | // Modified by Ivan Tcholakov, 16-JAN-2014. 417 | //public function attach($file, $disposition = '', $newname = NULL, $mime = '') { 418 | public function attach($file, $disposition = '', $newname = NULL, $mime = '', $embedded_image = false) { 419 | // 420 | 421 | $file = (string) $file; 422 | 423 | $disposition = (string) $disposition; 424 | 425 | if ($disposition == '') { 426 | $disposition ='attachment'; 427 | } 428 | 429 | $newname = (string) $newname; 430 | 431 | if ($newname == '') { 432 | // For making strict NULL checks happy. 433 | $newname = NULL; 434 | } 435 | 436 | $mime = (string) $mime; 437 | 438 | if ($this->mailer_engine == 'phpmailer') { 439 | 440 | if ($mime == '') { 441 | 442 | if (strpos($file, '://') === FALSE && ! file_exists($file)) { 443 | 444 | $this->_set_error_message('lang:email_attachment_missing', $file); 445 | // Modified by Ivan Tcholakov, 14-JAN-2014. 446 | //return FALSE; 447 | return $this; 448 | // 449 | } 450 | 451 | if (!$fp = @fopen($file, FOPEN_READ)) { 452 | 453 | $this->_set_error_message('lang:email_attachment_unreadable', $file); 454 | // Modified by Ivan Tcholakov, 14-JAN-2014. 455 | //return FALSE; 456 | return $this; 457 | // 458 | } 459 | 460 | $file_content = stream_get_contents($fp); 461 | $mime = $this->_mime_types(pathinfo($file, PATHINFO_EXTENSION)); 462 | fclose($fp); 463 | 464 | $this->_attachments[] = array( 465 | 'name' => array($file, $newname), 466 | 'disposition' => $disposition, 467 | 'type' => $mime, 468 | ); 469 | 470 | $newname = $newname === NULL ? basename($file) : $newname; 471 | $cid = $this->attachment_cid($file); 472 | 473 | } else { 474 | 475 | // A buffered file, in this case make sure that $newname has been set. 476 | 477 | $file_content =& $file; 478 | 479 | $this->_attachments[] = array( 480 | 'name' => array($newname, $newname), 481 | 'disposition' => $disposition, 482 | 'type' => $mime, 483 | ); 484 | 485 | $cid = $this->attachment_cid($newname); 486 | } 487 | 488 | if (empty($embedded_image)) { 489 | $this->phpmailer->addStringAttachment($file_content, $newname, 'base64', $mime, $disposition); 490 | } else { 491 | $this->phpmailer->addStringEmbeddedImage($file_content, $cid, $newname, 'base64', $mime, $disposition); 492 | } 493 | 494 | } else { 495 | 496 | parent::attach($file, $disposition, $newname, $mime); 497 | } 498 | 499 | return $this; 500 | } 501 | 502 | public function attachment_cid($filename) { 503 | 504 | if ($this->mailer_engine == 'phpmailer') { 505 | 506 | for ($i = 0, $c = count($this->_attachments); $i < $c; $i++) { 507 | 508 | if ($this->_attachments[$i]['name'][0] === $filename) { 509 | 510 | $this->_attachments[$i]['cid'] = uniqid(basename($this->_attachments[$i]['name'][0]).'@'); 511 | return $this->_attachments[$i]['cid']; 512 | } 513 | } 514 | 515 | } else { 516 | 517 | return parent::attachment_cid($filename); 518 | } 519 | 520 | return FALSE; 521 | } 522 | 523 | // Added by Ivan Tcholakov, 16-JAN-2014. 524 | public function get_attachment_cid($filename) { 525 | 526 | for ($i = 0, $c = count($this->_attachments); $i < $c; $i++) { 527 | 528 | if ($this->_attachments[$i]['name'][0] === $filename) { 529 | return empty($this->_attachments[$i]['cid']) ? FALSE : $this->_attachments[$i]['cid']; 530 | } 531 | } 532 | 533 | return FALSE; 534 | } 535 | 536 | public function set_header($header, $value) { 537 | 538 | $header = (string) $header; 539 | $value = (string) $value; 540 | 541 | if ($this->mailer_engine == 'phpmailer') { 542 | $this->phpmailer->addCustomHeader($header, str_replace(array("\n", "\r"), '', $value)); 543 | } 544 | 545 | parent::set_header($header, $value); 546 | 547 | return $this; 548 | } 549 | 550 | public function send($auto_clear = true) { 551 | 552 | $auto_clear = !empty($auto_clear); 553 | 554 | if ($this->mailer_engine == 'phpmailer') { 555 | 556 | if ($this->mailtype == 'html') { 557 | 558 | // Modified by Ivan Tcholakov, 01-AUG-2015. 559 | // See https://github.com/ivantcholakov/codeigniter-phpmailer/issues/8 560 | //$this->phpmailer->AltBody = $this->_get_alt_message(); 561 | $this->phpmailer->AltBody = str_replace(array('{unwrap}', '{/unwrap}'), '', $this->_get_alt_message()); 562 | // 563 | } 564 | 565 | switch ($this->oauth_type) { 566 | 567 | case 'xoauth2': 568 | 569 | $this->phpmailer->AuthType = 'XOAUTH2'; 570 | 571 | $this->phpmailer->setOAuth($this->oauth_instance); 572 | 573 | break; 574 | 575 | case 'xoauth2_google': 576 | 577 | $this->phpmailer->AuthType = 'XOAUTH2'; 578 | 579 | $provider = new \League\OAuth2\Client\Provider\Google( 580 | array( 581 | 'clientId' => $this->oauth_client_id, 582 | 'clientSecret' => $this->oauth_client_secret, 583 | ) 584 | ); 585 | 586 | $this->phpmailer->setOAuth(new \PHPMailer\PHPMailer\OAuth( 587 | array( 588 | 'provider' => $provider, 589 | 'clientId' => $this->oauth_client_id, 590 | 'clientSecret' => $this->oauth_client_secret, 591 | 'refreshToken' => $this->oauth_refresh_token, 592 | 'userName' => $this->oauth_user_email != '' ? $this->oauth_user_email : $this->smtp_user, 593 | ) 594 | ) 595 | ); 596 | 597 | break; 598 | 599 | case 'xoauth2_yahoo': 600 | 601 | $this->phpmailer->AuthType = 'XOAUTH2'; 602 | 603 | $provider = new \Hayageek\OAuth2\Client\Provider\Yahoo( 604 | array( 605 | 'clientId' => $this->oauth_client_id, 606 | 'clientSecret' => $this->oauth_client_secret, 607 | ) 608 | ); 609 | 610 | $this->phpmailer->setOAuth(new \PHPMailer\PHPMailer\OAuth( 611 | array( 612 | 'provider' => $provider, 613 | 'clientId' => $this->oauth_client_id, 614 | 'clientSecret' => $this->oauth_client_secret, 615 | 'refreshToken' => $this->oauth_refresh_token, 616 | 'userName' => $this->oauth_user_email != '' ? $this->oauth_user_email : $this->smtp_user, 617 | ) 618 | ) 619 | ); 620 | 621 | break; 622 | 623 | case 'xoauth2_microsoft': 624 | 625 | $this->phpmailer->AuthType = 'XOAUTH2'; 626 | 627 | $provider = new \Stevenmaguire\OAuth2\Client\Provider\Microsoft( 628 | array( 629 | 'clientId' => $this->oauth_client_id, 630 | 'clientSecret' => $this->oauth_client_secret, 631 | ) 632 | ); 633 | 634 | $this->phpmailer->setOAuth(new \PHPMailer\PHPMailer\OAuth( 635 | array( 636 | 'provider' => $provider, 637 | 'clientId' => $this->oauth_client_id, 638 | 'clientSecret' => $this->oauth_client_secret, 639 | 'refreshToken' => $this->oauth_refresh_token, 640 | 'userName' => $this->oauth_user_email != '' ? $this->oauth_user_email : $this->smtp_user, 641 | ) 642 | ) 643 | ); 644 | 645 | break; 646 | 647 | default: 648 | 649 | $this->phpmailer->AuthType = ''; 650 | 651 | $reflection = new \ReflectionClass($this->phpmailer); 652 | $property = $reflection->getProperty('oauth'); 653 | $property->setAccessible(true); 654 | $property->setValue($this->phpmailer, null); 655 | 656 | break; 657 | } 658 | 659 | $result = (bool) $this->phpmailer->send(); 660 | 661 | if ($result) { 662 | 663 | $this->_set_error_message('lang:email_sent', $this->_get_protocol()); 664 | 665 | if ($auto_clear) { 666 | $this->clear(); 667 | } 668 | 669 | } else { 670 | 671 | $this->_set_error_message($this->phpmailer->ErrorInfo); 672 | } 673 | 674 | } else { 675 | 676 | $result = parent::send($auto_clear); 677 | } 678 | 679 | return $result; 680 | } 681 | 682 | 683 | // Methods for setting configuration options ------------------------------- 684 | 685 | public function set_mailer_engine($mailer_engine) { 686 | 687 | $mailer_engine = strpos(strtolower($mailer_engine), 'phpmailer') !== false ? 'phpmailer' : 'codeigniter'; 688 | 689 | if ($this->mailer_engine == $mailer_engine) { 690 | return $this; 691 | } 692 | 693 | $this->mailer_engine = $mailer_engine; 694 | 695 | if ($mailer_engine == 'phpmailer') { 696 | 697 | if (!is_object($this->phpmailer)) { 698 | 699 | // Try to autoload the PHPMailer if there is already a registered autoloader. 700 | $phpmailer_class_exists = class_exists('PHPMailer\\PHPMailer\\PHPMailer', true); 701 | 702 | if (!$phpmailer_class_exists) { 703 | throw new \Exception('The class PHPMailer\\PHPMailer\\PHPMailer can not be found.'); 704 | } 705 | 706 | $this->phpmailer = new \PHPMailer\PHPMailer\PHPMailer(); 707 | \PHPMailer\PHPMailer\PHPMailer::$validator = 'valid_email'; 708 | } 709 | } 710 | 711 | $this->refresh_properties(); 712 | $this->clear(true); 713 | 714 | return $this; 715 | } 716 | 717 | public function set_useragent($useragent) { 718 | 719 | $useragent = (string) $useragent; 720 | 721 | $this->properties['useragent'] = $useragent; 722 | 723 | $this->set_mailer_engine($useragent); 724 | 725 | return $this; 726 | } 727 | 728 | public function set_mailpath($value) { 729 | 730 | $value = (string) $value; 731 | 732 | $this->properties['mailpath'] = $value; 733 | 734 | if ($this->mailer_engine == 'phpmailer') { 735 | $this->phpmailer->Sendmail = $value; 736 | } 737 | 738 | return $this; 739 | } 740 | 741 | public function set_protocol($protocol = 'mail') { 742 | 743 | $protocol = (string) $protocol; 744 | $protocol = in_array($protocol, self::$protocols, TRUE) ? strtolower($protocol) : 'mail'; 745 | 746 | $this->properties['protocol'] = $protocol; 747 | 748 | if ($this->mailer_engine == 'phpmailer') { 749 | 750 | switch ($protocol) { 751 | 752 | case 'mail': 753 | $this->phpmailer->isMail(); 754 | break; 755 | 756 | case 'sendmail': 757 | $this->phpmailer->isSendmail(); 758 | break; 759 | 760 | case 'smtp': 761 | $this->phpmailer->isSMTP(); 762 | break; 763 | } 764 | } 765 | 766 | return $this; 767 | } 768 | 769 | public function set_smtp_host($value) { 770 | 771 | $value = (string) $value; 772 | 773 | $this->properties['smtp_host'] = $value; 774 | 775 | if ($this->mailer_engine == 'phpmailer') { 776 | $this->phpmailer->Host = $value; 777 | } 778 | 779 | return $this; 780 | } 781 | 782 | // See https://github.com/ivantcholakov/codeigniter-phpmailer/issues/31 783 | public function set_smtp_auth($value) { 784 | 785 | $this->properties['smtp_auth'] = $value; 786 | 787 | $this->_smtp_auth = 788 | $value === NULL 789 | ? !($this->smtp_user == '' && $this->smtp_pass == '') 790 | : !empty($value); 791 | 792 | if ($this->mailer_engine == 'phpmailer') { 793 | $this->phpmailer->SMTPAuth = $this->_smtp_auth; 794 | } 795 | 796 | return $this; 797 | } 798 | 799 | public function set_smtp_user($value) { 800 | 801 | $value = (string) $value; 802 | 803 | $this->properties['smtp_user'] = $value; 804 | 805 | $this->_smtp_auth = 806 | $this->smtp_auth === NULL 807 | ? !($value == '' && $this->smtp_pass == '') 808 | : !empty($this->smtp_auth); 809 | 810 | if ($this->mailer_engine == 'phpmailer') { 811 | 812 | $this->phpmailer->Username = $value; 813 | $this->phpmailer->SMTPAuth = $this->_smtp_auth; 814 | } 815 | 816 | return $this; 817 | } 818 | 819 | public function set_smtp_pass($value) { 820 | 821 | $value = (string) $value; 822 | 823 | $this->properties['smtp_pass'] = $value; 824 | 825 | $this->_smtp_auth = 826 | $this->smtp_auth === NULL 827 | ? !($this->smtp_user == '' && $value == '') 828 | : !empty($this->smtp_auth); 829 | 830 | if ($this->mailer_engine == 'phpmailer') { 831 | 832 | $this->phpmailer->Password = $value; 833 | $this->phpmailer->SMTPAuth = $this->_smtp_auth; 834 | } 835 | 836 | return $this; 837 | } 838 | 839 | public function set_smtp_port($value) { 840 | 841 | $value = (int) $value; 842 | 843 | $this->properties['smtp_port'] = $value; 844 | 845 | if ($this->mailer_engine == 'phpmailer') { 846 | $this->phpmailer->Port = $value; 847 | } 848 | 849 | return $this; 850 | } 851 | 852 | public function set_smtp_timeout($value) { 853 | 854 | $value = (int) $value; 855 | 856 | $this->properties['smtp_timeout'] = $value; 857 | 858 | if ($this->mailer_engine == 'phpmailer') { 859 | $this->phpmailer->Timeout = $value; 860 | } 861 | 862 | return $this; 863 | } 864 | 865 | public function set_smtp_keepalive($value) { 866 | 867 | $value = !empty($value); 868 | 869 | $this->properties['smtp_keepalive'] = $value; 870 | 871 | if ($this->mailer_engine == 'phpmailer') { 872 | $this->phpmailer->SMTPKeepAlive = $value; 873 | } 874 | 875 | return $this; 876 | } 877 | 878 | public function set_smtp_crypto($smtp_crypto = '') { 879 | 880 | $smtp_crypto = trim(strtolower($smtp_crypto)); 881 | 882 | if ($smtp_crypto != 'tls' && $smtp_crypto != 'ssl') { 883 | $smtp_crypto = ''; 884 | } 885 | 886 | $this->properties['smtp_crypto'] = $smtp_crypto; 887 | 888 | if ($this->mailer_engine == 'phpmailer') { 889 | $this->phpmailer->SMTPSecure = $smtp_crypto; 890 | } 891 | 892 | return $this; 893 | } 894 | 895 | public function set_wordwrap($wordwrap = TRUE) { 896 | 897 | $wordwrap = !empty($wordwrap); 898 | 899 | $this->properties['wordwrap'] = $wordwrap; 900 | 901 | if ($this->mailer_engine == 'phpmailer') { 902 | $this->phpmailer->WordWrap = $wordwrap ? (int) $this->wrapchars : 0; 903 | } 904 | 905 | return $this; 906 | } 907 | 908 | public function set_wrapchars($wrapchars) { 909 | 910 | $wrapchars = (int) $wrapchars; 911 | 912 | $this->properties['wrapchars'] = $wrapchars; 913 | 914 | if ($this->mailer_engine == 'phpmailer') { 915 | 916 | if (!$this->wordwrap) { 917 | 918 | $this->phpmailer->WordWrap = 0; 919 | 920 | } else { 921 | 922 | if (empty($wrapchars)) { 923 | $wrapchars = 76; 924 | } 925 | 926 | $this->phpmailer->WordWrap = (int) $wrapchars; 927 | } 928 | } 929 | 930 | return $this; 931 | } 932 | 933 | public function set_mailtype($type = 'text') { 934 | 935 | $type = trim(strtolower($type)); 936 | $type = in_array($type, self::$mailtypes) ? $type : 'text'; 937 | 938 | $this->properties['mailtype'] = $type; 939 | 940 | if ($this->mailer_engine == 'phpmailer') { 941 | $this->phpmailer->isHTML($type == 'html'); 942 | } 943 | 944 | return $this; 945 | } 946 | 947 | public function set_charset($charset) { 948 | 949 | if ($charset == '') { 950 | $charset = config_item('charset'); 951 | } 952 | 953 | $charset = strtoupper($charset); 954 | 955 | $this->properties['charset'] = $charset; 956 | 957 | if ($this->mailer_engine == 'phpmailer') { 958 | $this->phpmailer->CharSet = $charset; 959 | } 960 | 961 | return $this; 962 | } 963 | 964 | // Not used by PHPMailer. 965 | public function set_multipart($value) { 966 | 967 | $this->properties['multipart'] = (string) $value; 968 | 969 | return $this; 970 | } 971 | 972 | public function set_alt_message($str) { 973 | 974 | $this->properties['alt_message'] = (string) $str; 975 | 976 | return $this; 977 | } 978 | 979 | public function set_validate($value) { 980 | 981 | $this->properties['validate'] = !empty($value); 982 | 983 | return $this; 984 | } 985 | 986 | public function set_priority($n = 3) { 987 | 988 | $n = preg_match('/^[1-5]$/', $n) ? (int) $n : 3; 989 | 990 | $this->properties['priority'] = $n; 991 | 992 | if ($this->mailer_engine == 'phpmailer') { 993 | $this->phpmailer->Priority = $n; 994 | } 995 | 996 | return $this; 997 | } 998 | 999 | public function set_newline($newline = "\n") { 1000 | 1001 | $newline = in_array($newline, array("\n", "\r\n", "\r")) ? $newline : "\n"; 1002 | 1003 | $this->properties['newline'] = $newline; 1004 | 1005 | if ($this->mailer_engine == 'phpmailer') { 1006 | 1007 | if (property_exists('\\PHPMailer\\PHPMailer\\PHPMailer', 'LE')) { 1008 | 1009 | $reflection = new \ReflectionProperty('\\PHPMailer\\PHPMailer\\PHPMailer', 'LE'); 1010 | $reflection->setAccessible(true); 1011 | $reflection->setValue(null, $newline); 1012 | } 1013 | } 1014 | 1015 | return $this; 1016 | } 1017 | 1018 | // A CodeIgniter specific option, PHPMailer uses the standard value "\r\n" only. 1019 | public function set_crlf($crlf = "\n") { 1020 | 1021 | $crlf = ($crlf !== "\n" && $crlf !== "\r\n" && $crlf !== "\r") ? "\n" : $crlf; 1022 | 1023 | $this->properties['crlf'] = $crlf; 1024 | 1025 | return $this; 1026 | } 1027 | 1028 | // Not used by PHPMailer. 1029 | public function set_dsn($value) { 1030 | 1031 | $this->properties['dsn'] = !empty($value); 1032 | 1033 | return $this; 1034 | } 1035 | 1036 | // Not used by PHPMailer. 1037 | public function set_send_multipart($value) { 1038 | 1039 | $this->properties['send_multipart'] = !empty($value); 1040 | 1041 | return $this; 1042 | } 1043 | 1044 | // Not used by PHPMailer. 1045 | public function set_bcc_batch_mode($value) { 1046 | 1047 | $this->properties['bcc_batch_mode'] = !empty($value); 1048 | 1049 | return $this; 1050 | } 1051 | 1052 | // Not used by PHPMailer. 1053 | public function set_bcc_batch_size($value) { 1054 | 1055 | $this->properties['bcc_batch_size'] = (int) $value; 1056 | 1057 | return $this; 1058 | } 1059 | 1060 | // PHPMailer's SMTP debug info level. 1061 | // 0 = off, 1 = commands, 2 = commands and data, 3 = as 2 plus connection status, 4 = low level data output. 1062 | public function set_smtp_debug($level) { 1063 | 1064 | $level = (int) $level; 1065 | 1066 | if ($level < 0) { 1067 | $level = 0; 1068 | } 1069 | 1070 | $this->properties['smtp_debug'] = $level; 1071 | 1072 | if ($this->mailer_engine == 'phpmailer') { 1073 | $this->phpmailer->SMTPDebug = $level; 1074 | } 1075 | 1076 | return $this; 1077 | } 1078 | 1079 | // PHPMailer's SMTP debug output. 1080 | // How to handle debug output. 1081 | // Options: 1082 | // `html` - the output gets escaped, line breaks are to be converted to `
`, appropriate for browser output; 1083 | // `echo` - the output is plain-text "as-is", it should be avoided in production web pages; 1084 | // `error_log` - the output is saved in error log as it is configured in php.ini; 1085 | // NULL or '' - default: 'echo' on CLI, 'html' otherwise. 1086 | // 1087 | // Alternatively, you can provide a callable expecting two params: a message string and the debug level: 1088 | // 1089 | // function custom_debug($str, $level) {echo "debug level $level; message: $str";}; 1090 | // $this->email->set_debug_output('custom_debug'); 1091 | // 1092 | public function set_debug_output($handle) { 1093 | 1094 | if ($handle === null 1095 | || 1096 | is_string($handle) && $handle == '' 1097 | ) { 1098 | $handle = self::$default_properties['debug_output']; 1099 | } 1100 | 1101 | $this->properties['debug_output'] = $handle; 1102 | 1103 | if ($this->mailer_engine == 'phpmailer') { 1104 | $this->phpmailer->Debugoutput = $handle; 1105 | } 1106 | 1107 | return $this; 1108 | } 1109 | 1110 | // Setting explicitly the body encoding. 1111 | // See https://github.com/ivantcholakov/codeigniter-phpmailer/issues/3 1112 | public function set_encoding($encoding) { 1113 | 1114 | $encoding = (string) $encoding; 1115 | 1116 | if (!in_array($encoding, $this->mailer_engine == 'phpmailer' ? self::$encodings_phpmailer : self::$encodings_ci)) { 1117 | $encoding = '8bit'; 1118 | } 1119 | 1120 | $this->properties['encoding'] = $encoding; 1121 | $this->_encoding = $encoding; 1122 | 1123 | if ($this->mailer_engine == 'phpmailer') { 1124 | $this->phpmailer->Encoding = $encoding; 1125 | } 1126 | 1127 | return $this; 1128 | } 1129 | 1130 | // PHPMailer: Whether to enable TLS encryption automatically if a server supports it, 1131 | // even if `SMTPSecure` is not set to 'tls'. 1132 | // Be aware that in PHP >= 5.6 this requires that the server's certificates are valid. 1133 | public function set_smtp_auto_tls($value) { 1134 | 1135 | $value = !empty($value); 1136 | 1137 | $this->properties['smtp_auto_tls'] = $value; 1138 | 1139 | if ($this->mailer_engine == 'phpmailer') { 1140 | $this->phpmailer->SMTPAutoTLS = $value; 1141 | } 1142 | 1143 | return $this; 1144 | } 1145 | 1146 | // PHPMailer: Options array passed to stream_context_create when connecting via SMTP. 1147 | // See https://github.com/ivantcholakov/codeigniter-phpmailer/issues/12 1148 | public function set_smtp_conn_options($value) { 1149 | 1150 | if (!is_array($value)) { 1151 | $value = array(); 1152 | } 1153 | 1154 | $this->properties['smtp_conn_options'] = $value; 1155 | 1156 | if ($this->mailer_engine == 'phpmailer') { 1157 | $this->phpmailer->SMTPOptions = $value; 1158 | } 1159 | 1160 | return $this; 1161 | } 1162 | 1163 | // XOAUTH2 settings. 1164 | 1165 | public function set_oauth_type($value) { 1166 | 1167 | $value = strtolower(trim((string) $value)); 1168 | 1169 | if ($value != '' && strpos($value, 'xoauth2') === false) { 1170 | $value = 'xoauth2'; 1171 | } 1172 | 1173 | $this->properties['oauth_type'] = $value; 1174 | 1175 | return $this; 1176 | } 1177 | 1178 | public function set_oauth_instance($value) { 1179 | 1180 | // An object that implements PHPMailer OAuthTokenProvider interface or null is expected here. 1181 | $this->properties['oauth_instance'] = $value; 1182 | 1183 | return $this; 1184 | } 1185 | 1186 | public function set_oauth_user_email($value) { 1187 | 1188 | $value = (string) $value; 1189 | 1190 | $this->properties['oauth_user_email'] = $value; 1191 | 1192 | return $this; 1193 | } 1194 | 1195 | public function set_oauth_client_id($value) { 1196 | 1197 | $value = (string) $value; 1198 | 1199 | $this->properties['oauth_client_id'] = $value; 1200 | 1201 | return $this; 1202 | } 1203 | 1204 | public function set_oauth_client_secret($value) { 1205 | 1206 | $value = (string) $value; 1207 | 1208 | $this->properties['oauth_client_secret'] = $value; 1209 | 1210 | return $this; 1211 | } 1212 | 1213 | public function set_oauth_refresh_token($value) { 1214 | 1215 | $value = (string) $value; 1216 | 1217 | $this->properties['oauth_refresh_token'] = $value; 1218 | 1219 | return $this; 1220 | } 1221 | 1222 | // DKIM signing, see https://github.com/ivantcholakov/codeigniter-phpmailer/issues/11 1223 | 1224 | // PHPMailer: DKIM signing domain name, for exmple 'example.com'. 1225 | public function set_dkim_domain($value) { 1226 | 1227 | $value = (string) $value; 1228 | 1229 | $this->properties['dkim_domain'] = $value; 1230 | 1231 | if ($this->mailer_engine == 'phpmailer') { 1232 | $this->phpmailer->DKIM_domain = $value; 1233 | } 1234 | 1235 | return $this; 1236 | } 1237 | 1238 | // PHPMailer: DKIM private key, set as a file path. 1239 | public function set_dkim_private($value) { 1240 | 1241 | $value = (string) $value; 1242 | 1243 | $this->properties['dkim_private'] = $value; 1244 | 1245 | // Parse the provided path seek for constant and translate it. 1246 | // For example the path to the private key could be set as follows: 1247 | // {APPPATH}config/rsa.private 1248 | $value_parsed = str_replace(array_keys(self::_get_file_name_variables()), array_values(self::_get_file_name_variables()), $value); 1249 | 1250 | if ($this->mailer_engine == 'phpmailer') { 1251 | $this->phpmailer->DKIM_private = $value_parsed; 1252 | } 1253 | 1254 | if ($value != '') { 1255 | 1256 | // Reset the alternative setting. 1257 | $this->set_dkim_private_string(''); 1258 | } 1259 | 1260 | return $this; 1261 | } 1262 | 1263 | // PHPMailer: DKIM private key, set directly from a string. 1264 | public function set_dkim_private_string($value) { 1265 | 1266 | $value = (string) $value; 1267 | 1268 | $this->properties['dkim_private_string'] = $value; 1269 | 1270 | if ($this->mailer_engine == 'phpmailer') { 1271 | $this->phpmailer->DKIM_private_string = $value; 1272 | } 1273 | 1274 | if ($value != '') { 1275 | 1276 | // Reset the alternative setting. 1277 | $this->set_dkim_private(''); 1278 | } 1279 | 1280 | return $this; 1281 | } 1282 | 1283 | // PHPMailer: DKIM selector. 1284 | public function set_dkim_selector($value) { 1285 | 1286 | $value = (string) $value; 1287 | 1288 | $this->properties['dkim_selector'] = $value; 1289 | 1290 | if ($this->mailer_engine == 'phpmailer') { 1291 | $this->phpmailer->DKIM_selector = $value; 1292 | } 1293 | 1294 | return $this; 1295 | } 1296 | 1297 | // PHPMailer: DKIM passphrase, used if your key is encrypted. 1298 | public function set_dkim_passphrase($value) { 1299 | 1300 | $value = (string) $value; 1301 | 1302 | $this->properties['dkim_passphrase'] = $value; 1303 | 1304 | if ($this->mailer_engine == 'phpmailer') { 1305 | $this->phpmailer->DKIM_passphrase = $value; 1306 | } 1307 | 1308 | return $this; 1309 | } 1310 | 1311 | // PHPMailer: DKIM Identity, usually the email address used as the source of the email. 1312 | public function set_dkim_identity($value) { 1313 | 1314 | $value = (string) $value; 1315 | 1316 | $this->properties['dkim_identity'] = $value; 1317 | 1318 | if ($this->mailer_engine == 'phpmailer') { 1319 | $this->phpmailer->DKIM_identity = $value; 1320 | } 1321 | 1322 | return $this; 1323 | } 1324 | 1325 | 1326 | // Overridden public methods ----------------------------------------------- 1327 | 1328 | public function valid_email($email) { 1329 | 1330 | if ($this->mailer_engine == 'phpmailer') { 1331 | 1332 | return valid_email($email); 1333 | } 1334 | 1335 | return parent::valid_email($email); 1336 | } 1337 | 1338 | 1339 | // Custom public methods --------------------------------------------------- 1340 | 1341 | public function full_html($subject, $message) { 1342 | 1343 | $full_html = 1344 | ' 1345 | 1346 | 1347 | 1348 | 1349 | '.htmlspecialchars($subject, ENT_QUOTES, $this->charset).' 1350 | 1351 | 1400 | 1401 | 1402 | 1403 | 1404 | 1405 | '.$message.' 1406 | 1407 | 1408 | '; 1409 | 1410 | return $full_html; 1411 | } 1412 | 1413 | 1414 | // Protected methods ------------------------------------------------------- 1415 | 1416 | protected function _get_alt_message() { 1417 | 1418 | $alt_message = (string) $this->alt_message; 1419 | 1420 | if ($alt_message == '') { 1421 | $alt_message = $this->_plain_text($this->_body); 1422 | } 1423 | 1424 | if ($this->mailer_engine == 'phpmailer') { 1425 | // PHPMailer would do the word wrapping. 1426 | return $alt_message; 1427 | } 1428 | 1429 | return ($this->wordwrap) 1430 | ? $this->word_wrap($alt_message, 76) 1431 | : $alt_message; 1432 | } 1433 | 1434 | protected function _plain_text($html) { 1435 | 1436 | if (!function_exists('html_to_text')) { 1437 | 1438 | $body = @ html_entity_decode($html, ENT_QUOTES, $this->charset); // Added by Ivan Tcholakov, 28-JUL-2013. 1439 | 1440 | $body = preg_match('/\(.*)\<\/body\>/si', $body, $match) ? $match[1] : $body; 1441 | $body = str_replace("\t", '', preg_replace('#