Skip to content

Commit 3c80c56

Browse files
committed
Add iCal event attachments and test case, fixes PHPMailer#47, thanks to @reblutus
Minor code cleanup Bundle EasyPeasyICS class in extras
1 parent 7f39eff commit 3c80c56

File tree

4 files changed

+171
-25
lines changed

4 files changed

+171
-25
lines changed

changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
* Fix cid generation in MsgHTML (Thanks to @digitalthought)
2323
* Fix handling of multiple SMTP servers (Thanks to @NanoCaiordo)
2424
* SMTP->Connect() now supports stream context options (Thanks to @stanislavdavid)
25+
* Add support for iCal event alternatives (Thanks to @reblutus)
2526

2627
## Version 5.2.6 (April 11th 2013)
2728
* Reflect move to PHPMailer GitHub organisation at https://github.com/PHPMailer/PHPMailer

class.phpmailer.php

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@
3535
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
3636
*/
3737

38-
if (version_compare(PHP_VERSION, '5.0.0', '<') ) exit("Sorry, this version of PHPMailer will only run on PHP version 5 or greater!\n");
38+
if (version_compare(PHP_VERSION, '5.0.0', '<') ) {
39+
exit("Sorry, PHPMailer will only run on PHP version 5 or greater!\n");
40+
}
3941

4042
/**
4143
* PHP email creation and transport class
@@ -91,8 +93,8 @@ class PHPMailer {
9193
public $FromName = 'Root User';
9294

9395
/**
94-
* Sets the Sender email (Return-Path) of the message. If not empty,
95-
* will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.
96+
* Sets the Sender email (Return-Path) of the message.
97+
* If not empty, will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.
9698
* @var string
9799
*/
98100
public $Sender = '';
@@ -111,21 +113,31 @@ class PHPMailer {
111113
public $Subject = '';
112114

113115
/**
114-
* Sets the Body of the message. This can be either an HTML or text body.
115-
* If HTML then run IsHTML(true).
116+
* An HTML or plain text message body.
117+
* If HTML then call IsHTML(true).
116118
* @var string
117119
*/
118120
public $Body = '';
119121

120122
/**
121-
* Sets the text-only body of the message. This automatically sets the
122-
* email to multipart/alternative. This body can be read by mail
123-
* clients that do not have HTML email capability such as mutt. Clients
124-
* that can read HTML will view the normal Body.
123+
* The plain-text message body.
124+
* This body can be read by mail clients that do not have HTML email
125+
* capability such as mutt & Eudora.
126+
* Clients that can read HTML will view the normal Body.
125127
* @var string
126128
*/
127129
public $AltBody = '';
128130

131+
/**
132+
* An iCal message part body
133+
* Only supported in simple alt or alt_inline message types
134+
* To generate iCal events, use the bundled extras/EasyPeasyICS.php class or iCalcreator
135+
* @link http://sprain.ch/blog/downloads/php-class-easypeasyics-create-ical-files-with-php/
136+
* @link http://kigkonsult.se/iCalcreator/
137+
* @var string
138+
*/
139+
public $Ical = '';
140+
129141
/**
130142
* Stores the complete compiled MIME message body.
131143
* @var string
@@ -1577,6 +1589,11 @@ public function CreateBody() {
15771589
$body .= $this->GetBoundary($this->boundary[1], '', 'text/html', '');
15781590
$body .= $this->EncodeString($this->Body, $this->Encoding);
15791591
$body .= $this->LE.$this->LE;
1592+
if(!empty($this->Ical)) {
1593+
$body .= $this->GetBoundary($this->boundary[1], '', 'text/calendar; method=REQUEST', '');
1594+
$body .= $this->EncodeString($this->Ical, $this->Encoding);
1595+
$body .= $this->LE.$this->LE;
1596+
}
15801597
$body .= $this->EndBoundary($this->boundary[1]);
15811598
break;
15821599
case 'alt_inline':

extras/EasyPeasyICS.php

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php
2+
3+
/* ------------------------------------------------------------------------ */
4+
/* EasyPeasyICS
5+
/* ------------------------------------------------------------------------ */
6+
/* Manuel Reinhard, [email protected]
7+
/* Twitter: @sprain
8+
/* Web: www.sprain.ch
9+
/*
10+
/* Built with inspiration by
11+
/" http://stackoverflow.com/questions/1463480/how-can-i-use-php-to-dynamically-publish-an-ical-file-to-be-read-by-google-calend/1464355#1464355
12+
/* ------------------------------------------------------------------------ */
13+
/* History:
14+
/* 2010/12/17 - Manuel Reinhard - when it all started
15+
/* ------------------------------------------------------------------------ */
16+
17+
class EasyPeasyICS {
18+
19+
protected $calendarName;
20+
protected $events = array();
21+
22+
23+
/**
24+
* Constructor
25+
* @param string $calendarName
26+
*/
27+
public function __construct($calendarName=""){
28+
$this->calendarName = $calendarName;
29+
}//function
30+
31+
32+
/**
33+
* Add event to calendar
34+
* @param string $calendarName
35+
*/
36+
public function addEvent($start, $end, $summary="", $description="", $url=""){
37+
$this->events[] = array(
38+
"start" => $start,
39+
"end" => $end,
40+
"summary" => $summary,
41+
"description" => $description,
42+
"url" => $url
43+
);
44+
}//function
45+
46+
47+
public function render($output = true){
48+
49+
//start Variable
50+
$ics = "";
51+
52+
//Add header
53+
$ics .= "BEGIN:VCALENDAR
54+
METHOD:PUBLISH
55+
VERSION:2.0
56+
X-WR-CALNAME:".$this->calendarName."
57+
PRODID:-//hacksw/handcal//NONSGML v1.0//EN";
58+
59+
//Add events
60+
foreach($this->events as $event){
61+
$ics .= "
62+
BEGIN:VEVENT
63+
UID:". md5(uniqid(mt_rand(), true)) ."@EasyPeasyICS.php
64+
DTSTAMP:" . gmdate('Ymd').'T'. gmdate('His') . "Z
65+
DTSTART:".gmdate('Ymd', $event["start"])."T".gmdate('His', $event["start"])."Z
66+
DTEND:".gmdate('Ymd', $event["end"])."T".gmdate('His', $event["end"])."Z
67+
SUMMARY:".str_replace("\n", "\\n", $event['summary'])."
68+
DESCRIPTION:".str_replace("\n", "\\n", $event['description'])."
69+
URL;VALUE=URI:".$event['url']."
70+
END:VEVENT";
71+
}//foreach
72+
73+
74+
//Footer
75+
$ics .= "
76+
END:VCALENDAR";
77+
78+
79+
if ($output) {
80+
//Output
81+
header('Content-type: text/calendar; charset=utf-8');
82+
header('Content-Disposition: inline; filename='.$this->calendarName.'.ics');
83+
echo $ics;
84+
} else {
85+
return $ics;
86+
}
87+
88+
}//function
89+
90+
}//class

test/phpmailerTest.php

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -874,7 +874,44 @@ function test_AltBody_Attachment()
874874
}
875875
}
876876

877-
/**
877+
/**
878+
* iCal event test
879+
*/
880+
function test_Ical()
881+
{
882+
$this->Mail->Body = 'This is the <strong>HTML</strong> part of the email.';
883+
$this->Mail->AltBody = 'This is the text part of the email.';
884+
$this->Mail->Subject .= ': iCal';
885+
$this->Mail->IsHTML(true);
886+
$this->BuildBody();
887+
require_once '../extras/EasyPeasyICS.php';
888+
$ICS = new EasyPeasyICS("PHPMailer test calendar");
889+
$ICS->addEvent(
890+
strtotime('tomorrow 10:00 Europe/Paris'),
891+
strtotime('tomorrow 11:00 Europe/Paris'),
892+
'PHPMailer iCal test',
893+
'A test of PHPMailer iCal support',
894+
'https://github.com/PHPMailer/PHPMailer'
895+
);
896+
$this->Mail->Ical = $ICS->render(false);
897+
$this->assertTrue($this->Mail->Send(), $this->Mail->ErrorInfo);
898+
$this->Mail->Body = 'Embedded Image: <img alt="phpmailer" src="cid:my-attach">' .
899+
'Here is an image!</a>.';
900+
$this->Mail->AltBody = 'This is the text part of the email.';
901+
$this->Mail->Subject .= ': iCal + inline';
902+
$this->Mail->IsHTML(true);
903+
$this->Mail->AddEmbeddedImage(
904+
'../examples/images/phpmailer.png',
905+
'my-attach',
906+
'phpmailer.png',
907+
'base64',
908+
'image/png'
909+
);
910+
$this->BuildBody();
911+
$this->assertTrue($this->Mail->Send(), $this->Mail->ErrorInfo);
912+
}
913+
914+
/**
878915
* Test sending multiple messages with separate connections
879916
*/
880917
function test_MultipleSend()
@@ -1139,21 +1176,22 @@ function test_Signing()
11391176
unlink($keyfile);
11401177
}
11411178

1142-
/**
1143-
* Test line break reformatting
1144-
*/
1145-
function test_LineBreaks()
1146-
{
1147-
$unixsrc = "Hello\nWorld\nAgain\n";
1148-
$macsrc = "Hello\rWorld\rAgain\r";
1149-
$windowssrc = "Hello\r\nWorld\r\nAgain\r\n";
1150-
$mixedsrc = "Hello\nWorld\rAgain\r\n";
1151-
$target = "Hello\r\nWorld\r\nAgain\r\n";
1152-
$this->assertEquals($target, PHPMailer::NormalizeBreaks($unixsrc), 'UNIX break reformatting failed');
1153-
$this->assertEquals($target, PHPMailer::NormalizeBreaks($macsrc), 'Mac break reformatting failed');
1154-
$this->assertEquals($target, PHPMailer::NormalizeBreaks($windowssrc), 'Windows break reformatting failed');
1155-
$this->assertEquals($target, PHPMailer::NormalizeBreaks($mixedsrc), 'Mixed break reformatting failed');
1156-
}
1179+
/**
1180+
* Test line break reformatting
1181+
*/
1182+
function test_LineBreaks()
1183+
{
1184+
$unixsrc = "Hello\nWorld\nAgain\n";
1185+
$macsrc = "Hello\rWorld\rAgain\r";
1186+
$windowssrc = "Hello\r\nWorld\r\nAgain\r\n";
1187+
$mixedsrc = "Hello\nWorld\rAgain\r\n";
1188+
$target = "Hello\r\nWorld\r\nAgain\r\n";
1189+
$this->assertEquals($target, PHPMailer::NormalizeBreaks($unixsrc), 'UNIX break reformatting failed');
1190+
$this->assertEquals($target, PHPMailer::NormalizeBreaks($macsrc), 'Mac break reformatting failed');
1191+
$this->assertEquals($target, PHPMailer::NormalizeBreaks($windowssrc), 'Windows break reformatting failed');
1192+
$this->assertEquals($target, PHPMailer::NormalizeBreaks($mixedsrc), 'Mixed break reformatting failed');
1193+
}
1194+
11571195
/**
11581196
* Miscellaneous calls to improve test coverage and some small tests
11591197
*/

0 commit comments

Comments
 (0)