/** * Splits the given text into a list of Fragments. This is roughly done by * reversing the text and parsing from the bottom to the top. This way we * can check for 'On <date>, <author> wrote:' lines above quoted blocks. * * @param string $text A email body. * @param string $encoding Optional encoding to be used when parsing the text. * @return array A list of parsed Fragments. */ public static function read($text, $encoding = null) { // Resets everything before starting self::$_foundVisible = false; self::$_fragments = array(); self::$_fragment = null; self::$_encoding = $encoding; // Check for multi-line reply headers. Some clients break up // the "On DATE, NAME <EMAIL> wrote:" line into multiple lines. $text = preg_replace_callback('/^(On.*wrote:)$/msU', function ($matches) { return str_replace("\n", ' ', $matches[1]); }, $text); // Normalize line breaks. $text = str_replace("\r\n", "\n", $text); // The text is reversed initially due to the way we check for hidden fragments. $text = Fragment::reverse($text, self::$_encoding); // Strip any extra new lines or spaces from start. $text = rtrim($text); // Split into lines. $lines = preg_split("/\n/", $text); // Scan each line of the email content. foreach ($lines as $line) { self::_scanLine($line); } // Free variables unset($text, $lines); // Finish up the final fragment. Finishing a fragment will detect any // attributes (hidden, signature, reply), and join each line into a string. self::_finishFragment(); // Now that parsing is done, reverse the order. self::$_fragments = array_reverse(self::$_fragments); return self::$_fragments; }