New in v5 - non-destructive HTML breaklines processor! Scroll to the bottom for details.


With these code changes, you can safely enable HTML priority for your mail queue. This code is basically a mini HTML parser and fixes invalid HTML (you'd be surprised how many mail clients send out invalid HTML!)

This also fixes the invalid HTML left behind by Kayako's breaklines processor. In addition, the code trims off some of the whitespace at the bottom of the HTML message, whether it's <br>'s or tags like <p>'s with nothing in them.

The reason this is important is because having invalid HTML will result in ticket posts not rendering properly in the Staff CP. They also cause emails with the complete ticket history (if you have that feature enabled) to render incorrectly. Applying this patch ensures the ticket post HTML is valid and keeps your Staff CP and outgoing emails looking beautiful.

This code is not 100% perfect - it does try to fix valid HTML in some situations.

For example:


When it really should be:

However, this is harmless and does not screw up the rendering of the ticket post in the Staff CP. I will be improving this code in the future, but for the time being it works quite nicely for us.

The file included with this project is for version 4.40.833 of Kayako. There is also a file for version 4.40.959 of Kayako. But, as I do not run version 959, I have no way to verify for myself that it works. Click on the Files tab to find the files and download either the 833 or the 959 version as appropriate for your Kayako install.

The file is: __modules/tickets/library/Ticket/class.SWIFT_TicketPost.php

Admin CP Settings

You would need to go to the Admin CP > Mail Parser > Settings and set the "Email Content Priority" to be "HTML" for any of this to be useful.

You will want to go to the Admin CP > Tickets > Settings and configure the "Allowable HTML Tags" and "Allowable HTML Tags Attributes". For ourselves, we have the following set up:

Allowed Tags:

Allowed Tag Attributes:


Version 1
  • Initial Release
Version 2
  • Remove <img> tags that reference attached images (they can't work) - however, keep <img> tags that reference a valid URL.
  • Better method to collapse extra <br>'s that ignores whitespace between the tags.
  • Made newline-to-<br> replacement for newlines in between < pre >< /pre > tags case insensitive.
Version 3
  • Fixed issue where the original ticket post body html is completely empty.
Version 4
  • Remove tags that look like <![ ... ]>
Version 5
  • New powerful HTML breaklines processor!

Powerful HTML Breaklines Processor (totally optional)

Kayako's default breaklines processor gives you the option of plain text string matching and regex pattern matching. Neither one is suitable for HTML emails! So, I developed my own HTML pattern matching language that works every time, and I have integrated it into this project. If you have an HTML email that looks like:

<blockquote type="whatever">
From: billgates@microsoft.com
... and so on ...

My pattern code to match that would look like "div blockquote b #^from:#i /b br /br ..." - this is basically a mix of HTML document tree traversal and regex pattern matching.

To enable this feature you must modify the class.SWIFT_MailParser.php file. At the very bottom of the file is a ProcessBreaklines function and in that function is a foreach loop - replace the loop with the following:

        foreach ($_breaklineCache as $_breaklineContainer) {

            if ($_breaklineContainer['isregexp'] == '1') {
                // This is a regular expression value.
                $_splitContainer = preg_split($_breaklineContainer['breakline'], $_emailContents);

                // If more than one item is in the array then the match was successful
                // and the reply is the first one.
                if (count($_splitContainer) > 1) {
                    // The regular expression was successful; return the first match, as it will be all
                    // the text before the regular expression matched.
                    $_emailContents = $_splitContainer[0];
                    $_emailContents .= '<!-- breakline was here -->';

                // If the regex doesn't match, try the next breakline.
            } else {
                // Process normally; not a regular expression value.
                $_breakContent = reversestrchr($_emailContents, $_breaklineContainer['breakline']);

                // The breakline matched; return the text from the beginning of the string up to the breakline.
                if ($_breakContent) {
                    $_emailContents = $_breakContent;
                    $_emailContents .= '<!-- breakline was here -->';

                // If it doesn't match, try the next breakline.

The only new code here is the $_emailContents .= '<!-- breakline was here -->'; which is added in 2 places.

The next step is to go into your Admin CP and delete all the stupid breaklines that will never work well with HTML emails. Yes, seriously, delete them all!

Now, add one breakline exactly as follows (set "Is Regex?" to Yes)


Now go to Admin CP > Templates > Templates > General and edit the following email templates:

...and any other email templates that you use...

For the HTML email templates you need to add the following to the top of the template right after the <font> tag:

<p>====== Please reply above this line ======</p>

And for the text email templates you need to add something similar to the very top of the template:

====== Please reply above this line ======

That's it for getting it to work. Now for a brief description of what happens...

  1. Your staff email goes out and has the ====== Please reply above this line ====== string in the email.
  2. Your customer replies to the email (above the aforementioned cutoff line of course).
  3. Kayako's built in breaklines parser chops off the email at the breakline, and my custom code adds a <!-- breakline was here --> to the end of the email body.
  4. The <!-- breakline was here --> tag is detected and the new powerful HTML breaklines code runs.
  5. My beautiful html ticket posts code cleans up the broken HTML.
  6. Voila!

The best part about this is that my breaklines processor is non-destructive. This means that my breaklines processor runs when you are viewing the ticket post and does not actually remove any data from your database. That way, you can experiment with new breaklines without worrying about accidentally losing parts of your customer's emails!

The sucky part about this is that all the breaklines are hard coded into the file. So you'll have to actually edit the PHP file if you want to add new breaklines. There's probably a better way to do this (Add code to the Admin CP?) but this works for us and as far as my boss is concerned, I am done. :)

I've had my HTML breaklines code running on our production server for a while now and have been adding HTML breaklines whenever I see an email come in that wasn't handled. I am up to about 20 different breaklines as follows (you can find these in the code):

// unknown mail client
p blockquote #^on\s#i a /a #\swrote:$#i br /br /blockquote /p

// unknown mail client
hr /hr font p b #from:#i /b #.*# br /br b #sent:#i /b #.*# br /br b #to:#i /b #.*# br /br /p /font

// mail from blackberry.net
hr /hr div b #from:#i /b /div div b #date:#i /b /div div b #to:#i /b /div

// mail from gmail.com
div #on\s.*\sat\s.*#i span /span #wrote:#i br /br blockquote /blockquote
div #^on\s.*$#i a /a #^.*wrote:$#i br /br blockquote /blockquote
br /br #^on\s.*\swrote:$#i br /br blockquote /blockquote

// mail from hotmail.com
hr /hr #^date:\s#i br /br #^subject:\s#i br /br #^from:\s#i br /br #^to:\s#i br /br

// blackberry wireless (using exchange?)
br /br div font b #^from$#i /b #^:\s.*$# br /br b #^sent$#i /b #^:\s.*$# br /br b #^to$#i /b #^:\s.*$# br /br /font /div

// verizon wireless
br /br div #-+\sreply\smessage\s-+#i br /br #^from:#i br /br #^to:#i /div

// X-Mailer: Apple Mail (2.1082)
br /br div div #^on\s.*\sat\s.*\swrote:$#iU /div br /br blockquote /blockquote /div

// X-Mailer: Microsoft Windows Live Mail 15.4.3538.513
div b #from:#i /b /div div b #sent:#i /b /div div b #to:#i /b /div div b #subject:#i /b /div

// X-Mailer: Microsoft Office Outlook 12.0
div p ?a b span #from:#i /span /b span #.*# br /br b #sent:#i /b #.*# br /br b #to:#i /b #.*# br /br /span /p /div

// X-Mailer: Microsoft Windows Mail 6.0.6002.18197
blockquote div #-+\soriginal\smessage\s-+#i /div div b #from:#i /b /div div b #to:#i /b /div div b #sent:#i /b /div /blockquote

// X-Mailer: Lotus Notes Release 8.5.1 September 28, 2009
br /br table tr td td table tr td font b /b /font /td /tr /table br /br table tr td font /font td font #to:#i /font /td /td /tr /table br /br table tr td font b #please\srespond\sto\s#i /b /font /td /tr /table

// X-Mailer: Microsoft Outlook 14.0
p b span #from:#i /span /b span #.*# br /br b #sent:#i /b #.*# br /br b #to:#i /b #.*# br /br b #subject:#i /b /span /p

// X-Mailer: iPhone Mail (9A405)
div br /br #on\s.*\sat\s.*#i a /a #.*wrote:#i /div div /div blockquote /blockquote

// X-Mailer: iPhone Mail (8C148)
div br /br br /br #on\s.*\sat\s.*#i a /a #.*wrote:#i /div div /div blockquote /blockquote

// X-Mailer: Verizon Webmail
span #^\s?on\s.*$#i span /span #^\s?wrote:$#i /span div /div

// X-Mailer: YahooMailWebService/
div font hr /hr b span #from:#i /span /b #.*# br /br b span #to:#i /span /b #.*# br /br b span #sent:#i /span /b #.*# br /br b span #subject:#i /span /b #.*# br /br /font /div

// X-Mailer: Motorola android mail 1.0
br /br #^\s*-+\s?original\smessage\s?-+\s*$#im br /br blockquote /blockquote

// X-Mailer: Lotus Domino Web Server Release 8.5.3 September 15, 2011
br /br font #^-+.*\swrote:\s-+$#im /font div div #to:\s#i br /br #from:\s#i br /br #date:\s#i br /br /div /div

// X-MimeOLE: Produced By Microsoft Exchange V6.5
p #^\s*-+\s?original\smessage\s?-+\s*$#im br /br #from:\s.*#i br /br #sent:\s.*#i br /br #to:\s.*#i br /br /p

// X-Mailer: YahooMailClassic/15.0.4 YahooMailWebService/
div /div b span #from:#i /span /b !br /br b span #to:#i /span /b !br /br b span #sent:#i /span /b !br /br b span #subject:#i /span /b

Project Information

  • Homepage: beautiful-html-ticket-posts
  • Category: Apps

Issue tracking

View all issues


Administrator: Marvin Herbold