Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calendar with attachments #10

Merged
merged 3 commits into from Jan 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
281 changes: 123 additions & 158 deletions Mail/mime.php
Expand Up @@ -899,138 +899,7 @@ public function get($params = null, $filename = null, $skip_head = false)
}

$this->checkParams();

$attachments = count($this->parts) > 0;
$html_images = count($this->html_images) > 0;
$html = strlen($this->htmlbody) > 0;
$calendar = strlen($this->calbody) > 0;
$has_text = strlen($this->txtbody) > 0;
$text = !$html && $has_text;
$mixed_params = array('preamble' => $this->build_params['preamble']);

switch (true) {
case $calendar && !$attachments && !$text && !$html:
$message = $this->addCalendarPart();
break;

case $calendar && !$attachments:
$message = $this->addAlternativePart($mixed_params);
if ($has_text) {
$this->addTextPart($message);
}
if ($html) {
$this->addHtmlPart($message);
}
$this->addCalendarPart($message);
break;

case $text && !$attachments:
$message = $this->addTextPart();
break;

case !$text && !$html && $attachments:
$message = $this->addMixedPart($mixed_params);
for ($i = 0; $i < count($this->parts); $i++) {
$this->addAttachmentPart($message, $this->parts[$i]);
}
break;

case $text && $attachments:
$message = $this->addMixedPart($mixed_params);
$this->addTextPart($message);
for ($i = 0; $i < count($this->parts); $i++) {
$this->addAttachmentPart($message, $this->parts[$i]);
}
break;

case $html && !$attachments && !$html_images:
if (isset($this->txtbody)) {
$message = $this->addAlternativePart();
$this->addTextPart($message);
$this->addHtmlPart($message);
} else {
$message = $this->addHtmlPart();
}
break;

case $html && !$attachments && $html_images:
// * Content-Type: multipart/alternative;
// * text
// * Content-Type: multipart/related;
// * html
// * image...
if (isset($this->txtbody)) {
$message = $this->addAlternativePart();
$this->addTextPart($message);

$ht = $this->addRelatedPart($message);
$this->addHtmlPart($ht);
for ($i = 0; $i < count($this->html_images); $i++) {
$this->addHtmlImagePart($ht, $this->html_images[$i]);
}
} else {
// * Content-Type: multipart/related;
// * html
// * image...
$message = $this->addRelatedPart();
$this->addHtmlPart($message);
for ($i = 0; $i < count($this->html_images); $i++) {
$this->addHtmlImagePart($message, $this->html_images[$i]);
}
}
/*
// #13444, #9725: the code below was a non-RFC compliant hack
// * Content-Type: multipart/related;
// * Content-Type: multipart/alternative;
// * text
// * html
// * image...
$message = $this->addRelatedPart();
if (isset($this->txtbody)) {
$alt = $this->addAlternativePart($message);
$this->addTextPart($alt);
$this->addHtmlPart($alt);
} else {
$this->addHtmlPart($message);
}
for ($i = 0; $i < count($this->html_images); $i++) {
$this->addHtmlImagePart($message, $this->html_images[$i]);
}
*/
break;

case $html && $attachments && !$html_images:
$message = $this->addMixedPart($mixed_params);
if (isset($this->txtbody)) {
$alt = $this->addAlternativePart($message);
$this->addTextPart($alt);
$this->addHtmlPart($alt);
} else {
$this->addHtmlPart($message);
}
for ($i = 0; $i < count($this->parts); $i++) {
$this->addAttachmentPart($message, $this->parts[$i]);
}
break;

case $html && $attachments && $html_images:
$message = $this->addMixedPart($mixed_params);
if (isset($this->txtbody)) {
$alt = $this->addAlternativePart($message);
$this->addTextPart($alt);
$rel = $this->addRelatedPart($alt);
} else {
$rel = $this->addRelatedPart($message);
}
$this->addHtmlPart($rel);
for ($i = 0; $i < count($this->html_images); $i++) {
$this->addHtmlImagePart($rel, $this->html_images[$i]);
}
for ($i = 0; $i < count($this->parts); $i++) {
$this->addAttachmentPart($message, $this->parts[$i]);
}
break;
}
$message = $this->buildBodyPart();

if (!isset($message)) {
return null;
Expand Down Expand Up @@ -1062,6 +931,110 @@ public function get($params = null, $filename = null, $skip_head = false)
}
}

/**
* Builds the main body MIME part for the email body. It will add a mixed part
* if attachments are found. If no attachments are found it will return an
* alternative part if several body texts are found (text, html, calendar),
* or a single part if only one body text is found.
*
* @return Mail_mimePart|null The corresponding part for the body or null.
*
* @see buildAlternativeParts
* @see buildHtmlParts
*/
private function buildBodyPart()
{
$attachments = count($this->parts) > 0;
$mixed_params = array('preamble' => $this->build_params['preamble']);
$message = null;

if ($attachments) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bad condition

$message = $this->addMixedPart($mixed_params);
$this->buildAlternativeParts($message, null);
for ($i = 0; $i < count($this->parts); $i++) {
$this->addAttachmentPart($message, $this->parts[$i]);
}
} else {
$message = $this->buildAlternativeParts(null, $mixed_params);
}

return $message;
}

/**
* Builds a single text, html, or calendar part only if one of them is found.
* If two or more parts are found, then an alternative part containing them is built.
*
* @param $parent_part Mail_mimePart|null The parent mime part to add
* the part or null
* @param $mixed_params array|null The needed params to create the
* part when no parent_part is
* received.
*
* @return null|object The main part built inside the method. I will be an
* alternative part or text, html, or calendar part.
* Null if no body texts are found.
*/
private function buildAlternativeParts($parent_part, $mixed_params)
{
$html = strlen($this->htmlbody) > 0;
$calendar = strlen($this->calbody) > 0;
$has_text = strlen($this->txtbody) > 0;
$alternatives_count = $html + $calendar + $has_text;

if ($alternatives_count > 1) {
$alt_part = $this->addAlternativePart($parent_part ?: $mixed_params);
} else {
$alt_part = null;
}

$dest_part = $alt_part ?: $parent_part;
$part = null;

if ($has_text) {
$part = $this->addTextPart($dest_part);
}
if ($html) {
$part = $this->buildHtmlParts($dest_part);
}
if ($calendar) {
$part = $this->addCalendarPart($dest_part);
}

return $dest_part ?: $part;
}

/**
* Builds html part as a single part or inside a related part with the html
* images thar were found.
*
* @param Mail_mimePart|null $parent_part The object to add the part to,
* or anything else if a new object
* is to be created.
*
* @return Mail_mimePart|null The created part or null if no htmlbody found.
*/
private function buildHtmlParts($parent_part)
{
if (!$this->htmlbody) {
return null;
}

$count_html_images = count($this->html_images);
if ($count_html_images > 0) {
$part = $this->addRelatedPart($parent_part);
$this->addHtmlPart($part);
} else {
$part = $this->addHtmlPart($parent_part);
}

for ($i = 0; $i < $count_html_images; $i++) {
$this->addHtmlImagePart($part, $this->html_images[$i]);
}

return $part;
}

/**
* Returns an array with the headers needed to prepend to the email
* (MIME-Version and Content-Type). Format of argument is:
Expand Down Expand Up @@ -1373,46 +1346,38 @@ protected function basename($filename)
*/
protected function contentHeaders()
{
$attachments = count($this->parts) > 0;
$html_images = count($this->html_images) > 0;
$html = strlen($this->htmlbody) > 0;
$calendar = strlen($this->calbody) > 0;
$has_text = strlen($this->txtbody) > 0;
$text = !$html && $has_text;
$headers = array();
$attachments = count($this->parts) > 0;
$html_images = count($this->html_images) > 0;
$html = strlen($this->htmlbody) > 0;
$calendar = strlen($this->calbody) > 0;
$has_text = strlen($this->txtbody) > 0;
$has_alternatives = ($html + $calendar + $has_text) > 1;
$headers = array();

// See get()
switch (true) {
case $calendar && !$attachments && !$html && !$has_text:
$headers['Content-Type'] = 'text/calendar';
case $has_text && !$attachments && !$has_alternatives:
$headers['Content-Type'] = 'text/plain';
break;

case $calendar && !$attachments:
$headers['Content-Type'] = 'multipart/alternative';
case $html && !$html_images && !$attachments && !$has_alternatives:
$headers['Content-Type'] = 'text/html';
break;

case $text && !$attachments:
$headers['Content-Type'] = 'text/plain';
case $html && $html_images && !$attachments && !$has_alternatives:
$headers['Content-Type'] = 'multiplart/related';
break;

case !$text && !$html && $attachments:
case $text && $attachments:
case $html && $attachments && !$html_images:
case $html && $attachments && $html_images:
$headers['Content-Type'] = 'multipart/mixed';
case $calendar && !$attachments && !$has_alternatives:
$headers['Content-Type'] = 'text/calendar';
break;

case $html && !$attachments && !$html_images && $has_text:
case $html && !$attachments && $html_images && $has_text:
case $has_alternatives && !$attachments:
$headers['Content-Type'] = 'multipart/alternative';
break;

case $html && !$attachments && !$html_images && !$has_text:
$headers['Content-Type'] = 'text/html';
break;

case $html && !$attachments && $html_images && !$has_text:
$headers['Content-Type'] = 'multipart/related';
case $attachments:
$headers['Content-Type'] = 'multipart/mixed';
break;

default:
Expand Down
1 change: 1 addition & 0 deletions package.xml
Expand Up @@ -86,6 +86,7 @@ using RFC2047 and/or RFC2231.</description>
<file baseinstalldir="Mail" name="test_Bug_20273.phpt" role="test" />
<file baseinstalldir="Mail" name="test_Bug_20563.phpt" role="test" />
<file baseinstalldir="Mail" name="test_Bug_20564.phpt" role="test" />
<file baseinstalldir="Mail" name="test_Bug_21027.phpt" role="test" />
</dir> <!-- /tests -->
<dir name="Mail">
<file baseinstalldir="/" name="mime.php" role="php" />
Expand Down