[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/metamta/parser/ -> PhabricatorMetaMTAEmailBodyParser.php (source)

   1  <?php
   2  
   3  final class PhabricatorMetaMTAEmailBodyParser {
   4  
   5    /**
   6     * Mails can have bodies such as
   7     *
   8     *   !claim
   9     *
  10     *   taking this task
  11     *
  12     * Or
  13     *
  14     *   !assign epriestley
  15     *
  16     *   please, take this task I took; its hard
  17     *
  18     * This function parses such an email body and returns a dictionary
  19     * containing a clean body text (e.g. "taking this task"), a $command
  20     * (e.g. !claim, !assign) and a $command_value (e.g. "epriestley" in the
  21     * !assign example.)
  22     *
  23     * @return dict
  24     */
  25    public function parseBody($body) {
  26      $body = $this->stripTextBody($body);
  27      $lines = explode("\n", trim($body));
  28      $first_line = head($lines);
  29  
  30      $command = null;
  31      $command_value = null;
  32      $matches = null;
  33      if (preg_match('/^!(\w+)\s*(\S+)?/', $first_line, $matches)) {
  34        $lines = array_slice($lines, 1);
  35        $body = implode("\n", $lines);
  36        $body = trim($body);
  37  
  38        $command = $matches[1];
  39        $command_value = idx($matches, 2);
  40      }
  41  
  42      return array(
  43        'body' => $body,
  44        'command' => $command,
  45        'command_value' => $command_value,
  46      );
  47    }
  48  
  49    public function stripTextBody($body) {
  50      return trim($this->stripSignature($this->stripQuotedText($body)));
  51    }
  52  
  53    private function stripQuotedText($body) {
  54  
  55      // Look for "On <date>, <user> wrote:". This may be split across multiple
  56      // lines. We need to be careful not to remove all of a message like this:
  57      //
  58      //   On which day do you want to meet?
  59      //
  60      //   On <date>, <user> wrote:
  61      //   > Let's set up a meeting.
  62  
  63      $start = null;
  64      $lines = phutil_split_lines($body);
  65      foreach ($lines as $key => $line) {
  66        if (preg_match('/^\s*>?\s*On\b/', $line)) {
  67          $start = $key;
  68        }
  69        if ($start !== null) {
  70          if (preg_match('/\bwrote:/', $line)) {
  71            $lines = array_slice($lines, 0, $start);
  72            $body = implode('', $lines);
  73            break;
  74          }
  75        }
  76      }
  77  
  78      // Outlook english
  79      $body = preg_replace(
  80        '/^\s*(> )?-----Original Message-----.*?/imsU',
  81        '',
  82        $body);
  83  
  84      // Outlook danish
  85      $body = preg_replace(
  86        '/^\s*(> )?-----Oprindelig Meddelelse-----.*?/imsU',
  87        '',
  88        $body);
  89  
  90      // See example in T3217.
  91      $body = preg_replace(
  92        '/^________________________________________\s+From:.*?/imsU',
  93        '',
  94        $body);
  95  
  96      return rtrim($body);
  97    }
  98  
  99    private function stripSignature($body) {
 100      // Quasi-"standard" delimiter, for lols see:
 101      //   https://bugzilla.mozilla.org/show_bug.cgi?id=58406
 102      $body = preg_replace(
 103        '/^-- +$.*/sm',
 104        '',
 105        $body);
 106  
 107      // Mailbox seems to make an attempt to comply with the "standard" but
 108      // omits the leading newline and uses an em dash?
 109      $body = preg_replace(
 110        "/\s*\xE2\x80\x94 \nSent from Mailbox\s*\z/su",
 111        '',
 112        $body);
 113  
 114      // HTC Mail application (mobile)
 115      $body = preg_replace(
 116        '/^\s*^Sent from my HTC smartphone.*/sm',
 117        '',
 118        $body);
 119  
 120      // Apple iPhone
 121      $body = preg_replace(
 122        '/^\s*^Sent from my iPhone\s*$.*/sm',
 123        '',
 124        $body);
 125  
 126      return rtrim($body);
 127    }
 128  
 129  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1