<?php
class
simpleMailTransmission {
protected
$to
=
array
();
protected
$subject
=
''
;
protected
$message
=
''
;
protected
$header
=
''
;
protected
$_to
=
array
();
protected
$_from
=
array
();
protected
$_cc
=
array
();
protected
$_bcc
=
array
();
protected
$_header
=
''
;
protected
$_template
=
''
;
protected
$_viewVars
=
array
();
protected
$_attachments
=
array
();
protected
$_boundary
= null;
protected
$_lang
=
'ja'
;
protected
$_encoding
=
'UTF-8'
;
protected
$_charset
=
'ISO-2022-JP'
;
protected
$_transferEncoding
=
'7bit'
;
protected
$_xMailer
=
'GEKIOKOPUNPUNMARU'
;
public
function
to(
$email
= null,
$name
= null) {
if
(
$email
=== null) {
return
$this
->_to;
}
return
$this
->_setEmail(
'_to'
,
$email
,
$name
);
}
public
function
addTo(
$email
,
$name
= null) {
return
$this
->_addEmail(
'_to'
,
$email
,
$name
);
}
public
function
cc(
$email
= null,
$name
= null) {
if
(
$email
=== null) {
return
$this
->_cc;
}
return
$this
->_setEmail(
'_cc'
,
$email
,
$name
);
}
public
function
addCc(
$email
,
$name
= null) {
return
$this
->_addEmail(
'_cc'
,
$email
,
$name
);
}
public
function
bcc(
$email
= null,
$name
= null) {
if
(
$email
=== null) {
return
$this
->_bcc;
}
return
$this
->_setEmail(
'_bcc'
,
$email
,
$name
);
}
public
function
addBcc(
$email
,
$name
= null) {
return
$this
->_addEmail(
'_bcc'
,
$email
,
$name
);
}
protected
function
_setEmail(
$varName
,
$email
,
$name
) {
if
(
is_array
(
$email
)) {
$list
=
array
();
foreach
(
$email
as
$key
=>
$value
) {
if
(
is_int
(
$key
)) {
$key
=
$value
;
}
if
(self::email(
$key
)) {
$list
[
$key
] =
$value
;
}
}
$this
->{
$varName
} =
$list
;
return
$this
;
}
if
(self::email(
$email
)) {
if
(
$name
=== null) {
$name
=
$email
;
}
$this
->{
$varName
} =
array
(
$email
=>
$name
);
}
return
$this
;
}
protected
function
_addEmail(
$varName
,
$email
,
$name
) {
if
(
is_array
(
$email
)) {
$list
=
array
();
foreach
(
$email
as
$key
=>
$value
) {
if
(
is_int
(
$key
)) {
$key
=
$value
;
}
if
(self::email(
$key
)) {
$list
[
$key
] =
$value
;
}
}
$this
->{
$varName
} =
array_merge
(
$this
->{
$varName
},
$list
);
return
$this
;
}
if
(self::email(
$email
)) {
if
(
$name
=== null) {
$name
=
$email
;
}
$this
->{
$varName
}[
$email
] =
$name
;
}
return
$this
;
}
public
function
from(
$email
= null,
$name
= null) {
if
(
$email
=== null) {
return
$this
->_from;
}
return
$this
->_setEmailSingle(
'_from'
,
$email
,
$name
);
}
protected
function
_setEmailSingle(
$varName
,
$email
,
$name
) {
$current
=
$this
->{
$varName
};
$this
->_setEmail(
$varName
,
$email
,
$name
);
if
(
count
(
$this
->{
$varName
}) !== 1) {
$this
->{
$varName
} =
$current
;
}
return
$this
;
}
public
function
subject(
$subject
= null) {
if
(
$subject
=== null) {
return
$this
->subject;
}
$this
->subject = (string)
$subject
;
return
$this
;
}
public
function
template(
$template
= false) {
if
(
$template
=== false) {
return
$this
->_template;
}
$this
->_template =
$template
;
return
$this
;
}
public
function
viewVars(
$viewVars
= null) {
if
(
$viewVars
=== null) {
return
$this
->_viewVars;
}
$this
->_viewVars =
array_merge
(
$this
->_viewVars, (
array
)
$viewVars
);
return
$this
;
}
public
function
attachments(
$attachments
= null) {
if
(
$attachments
=== null) {
return
$this
->_attachments;
}
$attach
=
array
();
foreach
((
array
)
$attachments
as
$name
=>
$fileInfo
) {
if
(!
is_array
(
$fileInfo
)) {
$fileInfo
=
array
(
'file'
=>
$fileInfo
);
}
if
(
empty
(
$fileInfo
[
'file'
])) {
return
'File not specified.'
;
}
$fileInfo
[
'file'
] =
realpath
(
$fileInfo
[
'file'
]);
if
(
$fileInfo
[
'file'
] === false || !
file_exists
(
$fileInfo
[
'file'
])) {
return
'File not found.'
;
}
if
(
is_int
(
$name
)) {
$name
=
basename
(
$fileInfo
[
'file'
]);
}
if
(!isset(
$fileInfo
[
'mimetype'
])) {
$fileInfo
[
'mimetype'
] =
'application/octet-stream'
;
}
$attach
[
$name
] =
$fileInfo
;
}
$this
->_attachments =
$attach
;
return
$this
;
}
public
function
addAttachments(
$attachments
) {
$current
=
$this
->_attachments;
$this
->attachments(
$attachments
);
$this
->_attachments =
array_merge
(
$current
,
$this
->_attachments);
return
$this
;
}
protected
function
_createBoundary() {
if
(!
empty
(
$this
->_attachments)) {
$this
->_boundary = md5(uniqid(time()));
}
}
protected
function
_addBoundaries() {
$this
->_createBoundary();
$msg
=
''
;
$contentIds
=
array_filter
((
array
)self::_extract(
$this
->_attachments,
'{s}.contentId'
));
$hasInlineAttachments
=
count
(
$contentIds
) > 0;
$hasAttachments
= !
empty
(
$this
->_attachments);
$boundary
=
$relBoundary
=
$textBoundary
=
$this
->_boundary;
if
(
$hasInlineAttachments
) {
$msg
.=
'--'
.
$boundary
.
"\n"
;
$msg
.=
'Content-Type: multipart/related; boundary="rel-'
.
$boundary
.
'"'
.
"\n\n"
;
$relBoundary
=
$textBoundary
=
'rel-'
.
$boundary
;
}
if
(isset(
$this
->message)) {
if
(
$textBoundary
!==
$boundary
||
$hasAttachments
) {
$msg
.=
'--'
.
$textBoundary
.
"\n"
;
$msg
.=
'Content-Type: text/plain; charset='
.
$this
->_charset.
"\n"
;
$msg
.=
'Content-Transfer-Encoding: '
.
$this
->_transferEncoding.
"\n\n"
;
}
$msg
.=
$this
->message.
"\n\n"
;
}
if
(
$hasInlineAttachments
) {
$attachments
=
$this
->_attachInlineFiles(
$relBoundary
);
$msg
.=
$attachments
.
"\n"
;
$msg
.=
'--'
.
$relBoundary
.
'--'
.
"\n\n"
;
}
if
(
$hasAttachments
) {
$attachments
=
$this
->_attachFiles(
$boundary
);
$msg
.=
$attachments
.
"\n"
;
}
if
(
$hasAttachments
) {
$msg
.=
'--'
.
$boundary
.
'--'
.
"\n\n"
;
}
return
$msg
;
}
protected
function
_attachInlineFiles(
$boundary
) {
$msg
=
''
;
foreach
(
$this
->_attachments
as
$filename
=>
$fileInfo
) {
if
(
empty
(
$fileInfo
[
'contentId'
]))
continue
;
$data
=
$this
->_readFile(
$fileInfo
[
'file'
]);
$msg
.=
'--'
.
$boundary
.
"\n"
;
$msg
.=
'Content-Type: '
.
$fileInfo
[
'mimetype'
].
"\n"
;
$msg
.=
'Content-Transfer-Encoding: base64'
.
"\n"
;
$msg
.=
'Content-ID: <'
.
$fileInfo
[
'contentId'
].
'>'
.
"\n"
;
$msg
.=
'Content-Disposition: inline; filename="'
.
$filename
.
'"'
.
"\n\n"
;
$msg
.=
$data
.
"\n\n"
;
}
return
$msg
;
}
protected
function
_attachFiles(
$boundary
) {
$msg
=
''
;
foreach
(
$this
->_attachments
as
$filename
=>
$fileInfo
) {
if
(!
empty
(
$fileInfo
[
'contentId'
]))
continue
;
$data
=
$this
->_readFile(
$fileInfo
[
'file'
]);
$msg
.=
'--'
.
$boundary
.
"\n"
;
$msg
.=
'Content-Type: '
.
$fileInfo
[
'mimetype'
].
"\n"
;
$msg
.=
'Content-Transfer-Encoding: base64'
.
"\n"
;
if
(!isset(
$fileInfo
[
'contentDisposition'
]) ||
$fileInfo
[
'contentDisposition'
]) {
$msg
.=
'Content-Disposition: attachment; filename="'
.
$filename
.
'"'
.
"\n\n"
;
}
$msg
.=
$data
.
"\n\n"
;
}
return
$msg
;
}
protected
function
_readFile(
$path
) {
return
chunk_split
(
base64_encode
(
file_get_contents
(
$path
)));
}
protected
function
email(
$check
) {
$hostName
=
'(?:[_a-z0-9][-_a-z0-9]*\.)*(?:[a-z0-9][-a-z0-9]{0,62})\.(?:(?:[a-z]{2}\.)?[a-z]{2,})'
;
$regex
=
'/^[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+)*@'
.
$hostName
.
'$/i'
;
return
self::_check(
$check
,
$regex
);
}
public
function
send(
$plainMessage
= null) {
if
(
empty
(
$this
->_from)) {
return
'From is not specified.'
;
}
if
(
empty
(
$this
->_to) &&
empty
(
$this
->_cc) &&
empty
(
$this
->_bcc)) {
return
'You need to specify at least one destination for to, cc or bcc.'
;
}
if
(!
file_exists
(
$this
->_template)) {
$this
->message = self::mce(
$plainMessage
);
}
else
{
$this
->message = self::mce(
$this
->createMessage());
}
if
(!
empty
(
$this
->_attachments))
$this
->message =
$this
->_addBoundaries();
$this
->header =
$this
->createHeader();
$this
->to =
$this
->createTo();
return
self::_send();
}
protected
function
_send() {
mb_language(
$this
->_lang);
mb_internal_encoding(
$this
->_encoding);
if
(!
empty
(
$this
->_attachments))
return
self::_sendWithAttachments();
if
(
empty
(
$this
->to)) {
return
mb_send_mail(null,
$this
->subject,
$this
->message,
$this
->header);
}
else
{
$_errors
=
array
();
foreach
(
$this
->to
as
$to
) {
if
(!mb_send_mail(
$to
,
$this
->subject,
$this
->message,
$this
->header))
$_errors
[
$to
] = false;
}
if
(
empty
(
$_errors
))
return
true;
return
$_errors
;
}
}
protected
function
_sendWithAttachments() {
$this
->message =
str_replace
(
"\n"
,
"\r\n"
,
$this
->message);
$this
->header =
str_replace
(
"\n"
,
"\r\n"
,
$this
->header);
if
(
empty
(
$this
->to)) {
return
mail(null, self::mem(
$this
->subject),
$this
->message,
$this
->header);
}
else
{
$_errors
=
array
();
foreach
(
$this
->to
as
$to
) {
if
(!mail(
$to
, self::mem(
$this
->subject),
$this
->message,
$this
->header))
$_errors
[
$to
] = false;
}
if
(
empty
(
$_errors
))
return
true;
return
$_errors
;
}
}
protected
function
createHeader() {
foreach
(
$this
->_from
as
$email
=>
$name
)
$this
->_header .=
'From: '
.self::mem(
$name
).
' <'
.
$email
.
'>'
.
"\n"
;
if
(!
empty
(
$this
->_cc)) {
$this
->_header .=
'Cc: '
;
foreach
(
$this
->_cc
as
$email
=>
$name
) {
$this
->_header .= self::mem(
$name
).
' <'
.
$email
.
'>'
.
","
;
}
$this
->_header = self::trimLastChar(
$this
->_header).
"\n"
;
}
if
(!
empty
(
$this
->_bcc)) {
$this
->_header .=
'Bcc: '
;
foreach
(
$this
->_bcc
as
$email
=>
$name
) {
$this
->_header .= self::mem(
$name
).
' <'
.
$email
.
'>'
.
","
;
}
$this
->_header = self::trimLastChar(
$this
->_header).
"\n"
;
}
$this
->_header .=
'X-Mailer: '
.
$this
->_xMailer.
"\n"
;
if
(!
empty
(
$this
->_attachments)) {
$this
->_header .=
'MIME-Version: 1.0'
.
"\n"
;
$this
->_header .=
'Content-Type: multipart/mixed; boundary='
.
$this
->_boundary.
"\n"
;
$this
->_header .=
'Content-Transfer-Encoding: '
.
$this
->_transferEncoding.
"\n"
;
}
return
$this
->_header;
}
protected
function
createTo() {
$t
=
array
();
if
(!
empty
(
$this
->_to)) {
foreach
(
$this
->_to
as
$email
=>
$name
) {
$t
[] = self::mem(
$name
).
' <'
.
$email
.
'>'
;
}
}
return
$t
;
}
protected
function
createMessage() {
$b
=
''
;
$tmp
=
file_get_contents
(
$this
->_template);
if
(
$tmp
) {
$varArray
=
array
();
if
(!
empty
(
$this
->_viewVars)) {
foreach
(
$this
->_viewVars
as
$varName
=>
$value
)
$varArray
[
'{%'
.
$varName
.
'%}'
] =
$value
;
}
$b
=
str_replace
(
array_keys
(
$varArray
) ,
array_values
(
$varArray
),
$tmp
);
}
return
$b
;
}
protected
function
_check(
$check
,
$regex
) {
if
(preg_match(
$regex
,
$check
))
return
true;
return
false;
}
protected
function
mem(
$var
) {
$internalEncoding
= function_exists(
'mb_internal_encoding'
);
if
(
$internalEncoding
) {
$restore
= mb_internal_encoding();
mb_internal_encoding(
$this
->_encoding);
}
$return
= mb_encode_mimeheader(
$var
,
$this
->_encoding,
'B'
);
if
(
$internalEncoding
) mb_internal_encoding(
$restore
);
return
$return
;
}
protected
function
mce(
$var
) {
return
mb_convert_encoding(
$var
,
$this
->_charset);
}
protected
function
trimLastChar(
$var
) {
return
substr
(
$var
, 0, -1);
}
protected
function
_extract(
array
$data
,
$path
) {
if
(
empty
(
$path
) || !preg_match(
'/[{]/'
,
$path
))
return
$data
;
$tokens
=
explode
(
'.'
,
$path
);
$_key
=
'__set_item__'
;
$context
=
array
(
$_key
=>
array
(
$data
));
foreach
(
$tokens
as
$token
) {
$next
=
array
();
foreach
(
$context
[
$_key
]
as
$item
) {
foreach
((
array
)
$item
as
$k
=>
$v
) {
if
(self::_matchToken(
$k
,
$token
)) {
$next
[] =
$v
;
}
}
}
$context
=
array
(
$_key
=>
$next
);
}
return
$context
[
$_key
];
}
protected
function
_matchToken(
$key
,
$token
) {
if
(
$token
===
'{n}'
)
return
is_numeric
(
$key
);
if
(
$token
===
'{s}'
)
return
is_string
(
$key
);
return
(
$key
===
$token
);
}
}