jenkins-bot has submitted this change and it was merged. ( 
https://gerrit.wikimedia.org/r/395566 )

Change subject: CRM-21521: read multipart-related inside report
......................................................................


CRM-21521: read multipart-related inside report

When a multipart-report email body's first part is
multipart-related, extract the text correctly instead of crashing.

This logic should handle all kinds of weird multipart nesting, up
to MAIL_MAX_RECURSION levels deep.

Bug: T181934
Change-Id: I736acde96885aa6f6dde87af8770de5f812ea3ad
---
M CRM/Utils/Mail/EmailProcessor.php
1 file changed, 105 insertions(+), 49 deletions(-)

Approvals:
  jenkins-bot: Verified
  Eileen: Looks good to me, approved



diff --git a/CRM/Utils/Mail/EmailProcessor.php 
b/CRM/Utils/Mail/EmailProcessor.php
index bb02bae..6ec7d65 100644
--- a/CRM/Utils/Mail/EmailProcessor.php
+++ b/CRM/Utils/Mail/EmailProcessor.php
@@ -35,6 +35,7 @@
 // before the 4.1 release
 define('EMAIL_ACTIVITY_TYPE_ID', NULL);
 define('MAIL_BATCH_SIZE', 50);
+define('MAIL_MAX_RECURSION', 10);
 
 /**
  * Class CRM_Utils_Mail_EmailProcessor.
@@ -286,55 +287,7 @@
                 $text = $mail->body->text;
               }
               elseif ($mail->body instanceof ezcMailMultipart) {
-                if ($mail->body instanceof ezcMailMultipartReport) {
-                  $part = $mail->body->getMachinePart();
-                  if ($part instanceof ezcMailDeliveryStatus) {
-                    foreach ($part->recipients as $rec) {
-                      if (isset($rec["Diagnostic-Code"])) {
-                        $text = $rec["Diagnostic-Code"];
-                        break;
-                      }
-                      elseif (isset($rec["Description"])) {
-                        $text = $rec["Description"];
-                        break;
-                      }
-                      // no diagnostic info present - try getting the human 
readable part
-                      elseif (isset($rec["Status"])) {
-                        $text = $rec["Status"];
-                        $textpart = $mail->body->getReadablePart();
-                        if ($textpart != NULL and isset($textpart->text)) {
-                          $text .= " " . $textpart->text;
-                        }
-                        else {
-                          $text .= " Delivery failed but no diagnostic code or 
description.";
-                        }
-                        break;
-                      }
-                    }
-                  }
-                  elseif ($part != NULL and isset($part->text)) {
-                    $text = $part->text;
-                  }
-                  elseif (($part = $mail->body->getReadablePart()) != NULL) {
-                    $text = $part->text;
-                  }
-                }
-                elseif ($mail->body instanceof ezcMailMultipartRelated) {
-                  foreach ($mail->body->getRelatedParts() as $part) {
-                    if (isset($part->subType) and $part->subType == 'plain') {
-                      $text = $part->text;
-                      break;
-                    }
-                  }
-                }
-                else {
-                  foreach ($mail->body->getParts() as $part) {
-                    if (isset($part->subType) and $part->subType == 'plain') {
-                      $text = $part->text;
-                      break;
-                    }
-                  }
-                }
+                $text = self::getTextFromMultipart($mail->body);
               }
 
               if (
@@ -475,4 +428,107 @@
     }
   }
 
+  /**
+   * @param \ezcMailMultipart $multipart
+   * @param int $recursionLevel
+   *
+   * @return array
+   */
+  protected static function getTextFromMultipart($multipart, $recursionLevel = 
0) {
+    if ($recursionLevel >= MAIL_MAX_RECURSION) {
+      return NULL;
+    }
+    $recursionLevel += 1;
+    $text = NULL;
+    if ($multipart instanceof ezcMailMultipartReport) {
+      $text = self::getTextFromMulipartReport($multipart, $recursionLevel);
+    }
+    elseif ($multipart instanceof ezcMailMultipartRelated) {
+      $text = self::getTextFromMultipartRelated($multipart, $recursionLevel);
+    }
+    else {
+      foreach ($multipart->getParts() as $part) {
+        if (isset($part->subType) and $part->subType === 'plain') {
+          $text = $part->text;
+        }
+        elseif ($part instanceof ezcMailMultipart) {
+          $text = self::getTextFromMultipart($part);
+        }
+        if ($text) {
+          break;
+        }
+      }
+    }
+    return $text;
+  }
+
+  /**
+   * @param \ezcMailMultipartRelated $related
+   * @param int $recursionLevel
+   *
+   * @return array
+   */
+  protected static function getTextFromMultipartRelated($related, 
$recursionLevel) {
+    $text = NULL;
+    foreach ($related->getRelatedParts() as $part) {
+      if (isset($part->subType) and $part->subType === 'plain') {
+        $text = $part->text;
+      }
+      elseif ($part instanceof ezcMailMultipart) {
+        $text = self::getTextFromMultipart($part, $recursionLevel);
+      }
+      if ($text) {
+        break;
+      }
+    }
+    return $text;
+  }
+
+  /**
+   * @param \ezcMailMultipartReport $multipart
+   * @param $recursionLevel
+   *
+   * @return array
+   */
+  protected static function getTextFromMulipartReport($multipart, 
$recursionLevel) {
+    $text = NULL;
+    $part = $multipart->getMachinePart();
+    if ($part instanceof ezcMailDeliveryStatus) {
+      foreach ($part->recipients as $rec) {
+        if (isset($rec["Diagnostic-Code"])) {
+          $text = $rec["Diagnostic-Code"];
+          break;
+        }
+        elseif (isset($rec["Description"])) {
+          $text = $rec["Description"];
+          break;
+        }
+        // no diagnostic info present - try getting the human readable part
+        elseif (isset($rec["Status"])) {
+          $text = $rec["Status"];
+          $textpart = $multipart->getReadablePart();
+          if ($textpart !== NULL and isset($textpart->text)) {
+            $text .= " " . $textpart->text;
+          }
+          else {
+            $text .= " Delivery failed but no diagnostic code or description.";
+          }
+          break;
+        }
+      }
+    }
+    elseif ($part !== NULL and isset($part->text)) {
+      $text = $part->text;
+    }
+    elseif (($part = $multipart->getReadablePart()) !== NULL) {
+      if (isset($part->text)) {
+        $text = $part->text;
+      }
+      elseif ($part instanceof ezcMailMultipart) {
+        $text = self::getTextFromMultipart($part, $recursionLevel);
+      }
+    }
+    return $text;
+  }
+
 }

-- 
To view, visit https://gerrit.wikimedia.org/r/395566
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I736acde96885aa6f6dde87af8770de5f812ea3ad
Gerrit-PatchSet: 5
Gerrit-Project: wikimedia/fundraising/crm/civicrm
Gerrit-Branch: master
Gerrit-Owner: Ejegg <[email protected]>
Gerrit-Reviewer: Eileen <[email protected]>
Gerrit-Reviewer: Mepps <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to