Skip to content
This repository

Added Email::attach_cid() returning CID which enables to embed an attachment to html #1585

Closed
wants to merge 6 commits into from

2 participants

Petr Heralecký Andrey Andreev
Petr Heralecký

Sorry there are few more changes in this one pull request, but every this changes are connected and can't be separate. Look at commits as in individual changes. Every these changes are directed for attaching inline images, but if some commit is insufficient or something, I can rewrite it.

If you want to try demo of this functins, I'm sending email to you with demo in few minutes.

Andrey Andreev narfbg commented on the diff
system/libraries/Email.php
((20 lines not shown))
  421 + }
  422 +
  423 + if ( ! $fp = fopen($filename, FOPEN_READ))
  424 + {
  425 + $this->_set_error_message('lang:email_attachment_unreadable', $filename);
  426 + unset($this->_attachments[$ind]);
  427 + return FALSE;
  428 + }
  429 +
  430 + $this->_attachments[$ind]['type'] = $this->_mime_types(pathinfo($filename, PATHINFO_EXTENSION));
  431 + $file_content = stream_get_contents($fp);
  432 + fclose($fp);
  433 + }
  434 + else
  435 + {
  436 + $file_content = $filename;
4
Andrey Andreev Collaborator
narfbg added a note

What is this for?

Petr Heralecký
melounek added a note

Looks like opportunity to attach plain text instead of filename, but you are right, this shouldn't be in this pull-request.
Should I do this pull-request again for actual version and without this mistake?

Andrey Andreev Collaborator
narfbg added a note

Yes, please.
Quite a lot of changes have been done to the Email library since this was submitted anyway. The $_attachments unification for example is already done.

Petr Heralecký
melounek added a note

Now I see it... the opportunity to attach buffer instead of filename is already there https://github.com/melounek/CodeIgniter/blob/develop/system/libraries/Email.php#L1367
documented there https://github.com/melounek/CodeIgniter/blob/develop/user_guide_src/source/changelog.rst (find "email library")

anyway... today I will send actual pull request...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Andrey Andreev
Collaborator

Replaced by #2807.

Andrey Andreev narfbg closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
1  system/language/english/email_lang.php
@@ -29,6 +29,7 @@
29 29 $lang['email_invalid_address'] = "Invalid email address: %s";
30 30 $lang['email_attachment_missing'] = "Unable to locate the following email attachment: %s";
31 31 $lang['email_attachment_unreadable'] = "Unable to open this attachment: %s";
  32 +$lang['email_attachment_not_attached'] = "Attachment '%s' probably wasn not correctly attached.";
32 33 $lang['email_no_recipients'] = "You must include recipients: To, Cc, or Bcc";
33 34 $lang['email_send_failure_phpmail'] = "Unable to send email using PHP mail(). Your server might not be configured to send mail using this method.";
34 35 $lang['email_send_failure_sendmail'] = "Unable to send email using PHP Sendmail. Your server might not be configured to send mail using this method.";
113 system/libraries/Email.php
@@ -51,7 +51,7 @@ class CI_Email {
51 51 public $wrapchars = 76; // Number of characters to wrap at.
52 52 public $mailtype = 'text'; // text/html Defines email formatting
53 53 public $charset = 'utf-8'; // Default char set: iso-8859-1 or us-ascii
54   - public $multipart = 'mixed'; // "mixed" (in the body) or "related" (separate)
  54 + public $multipart = 'related'; // "related" (separate) or "mixed" (in the body)
55 55 public $alt_message = ''; // Alternative message for HTML emails
56 56 public $validate = FALSE; // TRUE/FALSE. Enables email validation
57 57 public $priority = 3; // Default priority (1 - 5)
@@ -81,9 +81,7 @@ class CI_Email {
81 81 protected $_cc_array = array();
82 82 protected $_bcc_array = array();
83 83 protected $_headers = array();
84   - protected $_attach_name = array();
85   - protected $_attach_type = array();
86   - protected $_attach_disp = array();
  84 + protected $_attachments = array();
87 85 protected $_protocols = array('mail', 'sendmail', 'smtp');
88 86 protected $_base_charsets = array('us-ascii', 'iso-2022-'); // 7-bit charsets (excluding language suffix)
89 87 protected $_bit_depths = array('7bit', '8bit');
@@ -171,9 +169,7 @@ public function clear($clear_attachments = FALSE)
171 169
172 170 if ($clear_attachments !== FALSE)
173 171 {
174   - $this->_attach_name = array();
175   - $this->_attach_type = array();
176   - $this->_attach_disp = array();
  172 + $this->_attachments = array();
177 173 }
178 174
179 175 return $this;
@@ -409,11 +405,62 @@ public function message($body)
409 405 */
410 406 public function attach($filename, $disposition = '', $newname = NULL, $mime = '')
411 407 {
412   - $this->_attach_name[] = array($filename, $newname);
413   - $this->_attach_disp[] = empty($disposition) ? 'attachment' : $disposition; // Can also be 'inline' Not sure if it matters
414   - $this->_attach_type[] = $mime;
  408 + $ind = count($this->_attachments); // incremented index of attachments
  409 + $this->_attachments[$ind]['name'] = array($filename,$newname);
  410 + $this->_attachments[$ind]['disp'] = empty($disposition) ? 'attachment' : $disposition;
  411 + $this->_attachments[$ind]['type'] = $mime;
  412 + $this->_attachments[$ind]['cid'] = NULL;
  413 +
  414 + if ($this->_attachments[$ind]['type'] === '')
  415 + {
  416 + if ( ! file_exists($filename))
  417 + {
  418 + $this->_set_error_message('lang:email_attachment_missing', $filename);
  419 + unset($this->_attachments[$ind]);
  420 + return FALSE;
  421 + }
  422 +
  423 + if ( ! $fp = fopen($filename, FOPEN_READ))
  424 + {
  425 + $this->_set_error_message('lang:email_attachment_unreadable', $filename);
  426 + unset($this->_attachments[$ind]);
  427 + return FALSE;
  428 + }
  429 +
  430 + $this->_attachments[$ind]['type'] = $this->_mime_types(pathinfo($filename, PATHINFO_EXTENSION));
  431 + $file_content = stream_get_contents($fp);
  432 + fclose($fp);
  433 + }
  434 + else
  435 + {
  436 + $file_content = $filename;
  437 + }
  438 +
  439 + $this->_attachments[$ind]['content'] = chunk_split(base64_encode($file_content));
  440 +
415 441 return $this;
416 442 }
  443 +
  444 + // --------------------------------------------------------------------
  445 +
  446 + /**
  447 + * Sets and return id of attachment (useful for attached inline pictures)
  448 + *
  449 + * @param string
  450 + * @return id
  451 + */
  452 + public function attach_cid($filename)
  453 + {
  454 + foreach($this->_attachments as $ind => $attach)
  455 + {
  456 + if($attach['name'][0] == $filename)
  457 + {
  458 + $this->_attachments[$ind]['cid'] = uniqid(basename($this->_attachments[$ind]['name'][0]) . "@");
  459 + return $this->_attachments[$ind]['cid'];
  460 + }
  461 + }
  462 + return FALSE;
  463 + }
417 464
418 465 // --------------------------------------------------------------------
419 466
@@ -629,9 +676,9 @@ protected function _get_content_type()
629 676 {
630 677 if ($this->mailtype === 'html')
631 678 {
632   - return (count($this->_attach_name) === 0) ? 'html' : 'html-attach';
  679 + return (count($this->_attachments) === 0) ? 'html' : 'html-attach';
633 680 }
634   - elseif ($this->mailtype === 'text' && count($this->_attach_name) > 0)
  681 + elseif ($this->mailtype === 'text' && count($this->_attachments) > 0)
635 682 {
636 683 return 'plain-attach';
637 684 }
@@ -1036,45 +1083,19 @@ protected function _build_message()
1036 1083 }
1037 1084
1038 1085 $attachment = array();
1039   - for ($i = 0, $c = count($this->_attach_name), $z = 0; $i < $c; $i++)
  1086 + for ($i = 0, $c = count($this->_attachments), $z = 0; $i < $c; $i++)
1040 1087 {
1041   - $filename = $this->_attach_name[$i][0];
1042   - $basename = is_null($this->_attach_name[$i][1]) ? basename($filename) : $this->_attach_name[$i][1];
1043   - $ctype = $this->_attach_type[$i];
1044   - $file_content = '';
1045   -
1046   - if ($this->_attach_type[$i] === '')
1047   - {
1048   - if ( ! file_exists($filename))
1049   - {
1050   - $this->_set_error_message('lang:email_attachment_missing', $filename);
1051   - return FALSE;
1052   - }
1053   -
1054   - $file = filesize($filename) +1;
1055   -
1056   - if ( ! $fp = fopen($filename, FOPEN_READ))
1057   - {
1058   - $this->_set_error_message('lang:email_attachment_unreadable', $filename);
1059   - return FALSE;
1060   - }
1061   -
1062   - $ctype = $this->_mime_types(pathinfo($filename, PATHINFO_EXTENSION));
1063   - $file_content = fread($fp, $file);
1064   - fclose($fp);
1065   - }
1066   - else
1067   - {
1068   - $file_content =& $this->_attach_content[$i];
1069   - }
  1088 + $filename = $this->_attachments[$i]['name'][0];
  1089 + $basename = is_null($this->_attachments[$i]['name'][1]) ? basename($filename) : $this->_attachments[$i]['name'][1];
1070 1090
1071 1091 $attachment[$z++] = '--'.$this->_atc_boundary.$this->newline
1072   - .'Content-type: '.$ctype.'; '
  1092 + .'Content-type: '.$this->_attachments[$i]['type'].'; '
1073 1093 .'name="'.$basename.'"'.$this->newline
1074   - .'Content-Disposition: '.$this->_attach_disp[$i].';'.$this->newline
1075   - .'Content-Transfer-Encoding: base64'.$this->newline;
  1094 + .'Content-Disposition: '.$this->_attachments[$i]['disp'].';'.$this->newline
  1095 + .'Content-Transfer-Encoding: base64'.$this->newline
  1096 + .($this->_attachments[$i]['cid'] ? "Content-ID: <".$this->_attachments[$i]['cid'].">".$this->newline : '');
1076 1097
1077   - $attachment[$z++] = chunk_split(base64_encode($file_content));
  1098 + $attachment[$z++] = $this->_attachments[$i]['content'];
1078 1099 }
1079 1100
1080 1101 $body .= implode($this->newline, $attachment).$this->newline.'--'.$this->_atc_boundary.'--';
5 user_guide_src/source/changelog.rst
Source Rendered
@@ -138,6 +138,11 @@ Release Date: Not Released
138 138 - CI_Loader::_ci_autoloader() is now a protected method.
139 139 - Added custom filename to Email::attach() as $this->email->attach($filename, $disposition, $newname).
140 140 - Added possibility to send attachment as buffer string in Email::attach() as $this->email->attach($buffer, $disposition, $newname, $mime).
  141 + - Email attachments are creating in function Email::attach() - it's faster for sending many emails with same attachments
  142 + - Email attachments opening by stream_get_contents() instead of fread. Thats enable to attach file paths a whole urls.
  143 + - Added method Email::attach_cid() returning CID which enables to embed an attachment to html.
  144 + - Unification of Email properties like Email->attach_name etc... to one associative array Email->_attachments
  145 + - Change multipart type from mixed to related in Email library. It makes better results in some Email clients especially for inlnine attachments.
141 146 - :doc:`Cart library <libraries/cart>` changes include:
142 147 - It now auto-increments quantity's instead of just resetting it, this is the default behaviour of large e-commerce sites.
143 148 - Product Name strictness can be disabled via the Cart Library by switching "$product_name_safe".
24 user_guide_src/source/libraries/email.rst
Source Rendered
@@ -230,8 +230,8 @@ $this->email->attach()
230 230 ----------------------
231 231
232 232 Enables you to send an attachment. Put the file path/name in the first
233   -parameter. Note: Use a file path, not a URL. For multiple attachments
234   -use the function multiple times. For example::
  233 +parameter. For multiple attachments use the function multiple times.
  234 +For example::
235 235
236 236 $this->email->attach('/path/to/photo1.jpg');
237 237 $this->email->attach('/path/to/photo2.jpg');
@@ -252,6 +252,26 @@ parameter as mime-type::
252 252
253 253 $this->email->attach($buffer, 'attachment', 'report.pdf', 'application/pdf');
254 254
  255 +$this->email->attach_cid()
  256 +--------------------------
  257 +
  258 +Returns CID which enables to embed an attachment to html. First parameter
  259 +must be attached file.
  260 +
  261 +::
  262 +
  263 + $filename = '/img/photo1.jpg';
  264 + $this->email->attach($filename);
  265 + foreach ($list as $address)
  266 + {
  267 + $this->email->to($address);
  268 + $cid = $this->email->attach_cid($filename);
  269 + $this->email->message('<img src='cid:". $cid ."' alt="photo1" />');
  270 + $this->email->send();
  271 + }
  272 +
  273 +CID for each Email have to be create again to be unique.
  274 +
255 275 $this->email->print_debugger()
256 276 -------------------------------
257 277

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.