diff --git a/include/class.mailfetch.php b/include/class.mailfetch.php index 363589b46ab2f9720960ac4a8084e80793d9f67c..90c7e047f41a4ed3eb97287af64a30687fec6b57 100644 --- a/include/class.mailfetch.php +++ b/include/class.mailfetch.php @@ -543,11 +543,21 @@ class MailFetcher { } function getPriority($mid) { - if ($this->tnef && isset($this->tnef->Importance)) - // PidTagImportance is 0, 1, or 2 + if ($this->tnef && isset($this->tnef->Importance)) { + // PidTagImportance is 0, 1, or 2, 2 is high // http://msdn.microsoft.com/en-us/library/ee237166(v=exchg.80).aspx - return $this->tnef->Importance + 1; - return Mail_Parse::parsePriority($this->getHeader($mid)); + $urgency = 4 - $this->tnef->Importance; + } + elseif ($priority = Mail_Parse::parsePriority($this->getHeader($mid))) { + $urgency = $priority + 1; + } + if ($urgency) { + $sql = 'SELECT `priority_id` FROM '.PRIORITY_TABLE + .' WHERE `priority_urgency`='.db_input($urgency) + .' LIMIT 1'; + $id = db_result(db_query($sql)); + return $id; + } } function getBody($mid) { diff --git a/include/class.mailparse.php b/include/class.mailparse.php index 2a91faf7f451b789a107e4fbe691b4ff50ac0bb5..ed171ff32cfa76ad8e2a416cd09ca6b71c42799b 100644 --- a/include/class.mailparse.php +++ b/include/class.mailparse.php @@ -462,43 +462,59 @@ class Mail_Parse { return $files; } - function getPriority(){ - if ($this->tnef && isset($this->tnef->Importance)) - // PidTagImportance is 0, 1, or 2 + function getPriority() { + if ($this->tnef && isset($this->tnef->Importance)) { + // PidTagImportance is 0, 1, or 2, 2 is high // http://msdn.microsoft.com/en-us/library/ee237166(v=exchg.80).aspx - return $this->tnef->Importance + 1; - - return Mail_Parse::parsePriority($this->getHeader()); + $urgency = 4 - $this->tnef->Importance; + } + elseif ($priority = Mail_Parse::parsePriority($this->getHeader())) { + $urgency = $priority + 1; + } + if ($urgency) { + $sql = 'SELECT `priority_id` FROM '.PRIORITY_TABLE + .' WHERE `priority_urgency`='.db_input($urgency) + .' LIMIT 1'; + $id = db_result(db_query($sql)); + return $id; + } } + /** + * Return a normalized priority urgency from the email headers received. + * + * Returns: + * (int) priority urgency, {1,2,3}, where 1 is high. Returns 0 if no + * priority could be inferred from the headers. + * + * References: + * https://github.com/osTicket/osTicket-1.8/issues/1674 + * http://stackoverflow.com/questions/15568583/php-mail-priority-types + */ static function parsePriority($header=null){ - if (! $header) - return 0; - // Test for normal "X-Priority: INT" style header & stringy version. - // Allows for Importance possibility. - $matching_char = ''; - if (preg_match ( '/priority: (\d|\w)/i', $header, $matching_char ) - || preg_match ( '/importance: (\d|\w)/i', $header, $matching_char )) { - switch ($matching_char[1]) { - case 'h' : - case 'H' :// high - case 'u': - case 'U': //Urgent - case 6 : - case 5 : - return 1; - case 'n' : // normal - case 'N' : - case 4 : - case 3 : - return 2; - case 'l' : // low - case 'L' : - case 2 : - case 1 : - return 3; - } + if (!$header) + return 0; + + // Test for normal "X-Priority: INT" style header & stringy version. + // Allows for Importance possibility. + $matching_char = ''; + if (preg_match('/(?:priority|importance): (\w)/i', $header, $matching_char)) { + switch (strtoupper($matching_char[1])) { + case 'H' :// high + case 'U': //Urgent + case '2' : + case '1' : + return 1; + case 'N' : + case '4' : + case '3' : + return 2; + case 'L' : + case '6' : + case '5' : + return 3; + } } return 0; } diff --git a/setup/test/tests/test.header_functions.php b/setup/test/tests/test.header_functions.php index b64a1c400946e590e01a8742d47d9a09ffefbd46..0b2328ce4f30cd42ea6ee09a3e51fd138ffffb91 100644 --- a/setup/test/tests/test.header_functions.php +++ b/setup/test/tests/test.header_functions.php @@ -5,65 +5,67 @@ define('PEAR_DIR', INCLUDE_DIR.'/pear/'); require_once INCLUDE_DIR."class.mailparse.php"; abstract class Priorities { - const HIGH_PRIORITY = 1; - const NORMAL_PRIORITY = 2; - const LOW_PRIORITY = 3; - const NO_PRIORITY = 0; + const HIGH_PRIORITY = 1; + const NORMAL_PRIORITY = 2; + const LOW_PRIORITY = 3; + const NO_PRIORITY = 0; } class TestHeaderFunctions extends Test { var $name = "Email Header Function Algorithm Regression Tests."; - + function testMailParsePriority() { - $func_class_method = array('Mail_Parse','parsePriority'); - $strlen_base = strlen($this->h()); + $func_class_method = array('Mail_Parse','parsePriority'); + $strlen_base = strlen($this->h()); + + foreach ( array ( + // input => output + 'X-Priority: isNAN' => Priorities::NO_PRIORITY, + 'X-Priority: 1' => Priorities::HIGH_PRIORITY, + 'X-Priority: 2' => Priorities::HIGH_PRIORITY, + 'X-Priority: 3' => Priorities::NORMAL_PRIORITY, + 'X-Priority: 4' => Priorities::NORMAL_PRIORITY, + 'X-Priority: 5' => Priorities::LOW_PRIORITY, + 'X-Priority: 6' => Priorities::LOW_PRIORITY, + 'No priority set' => Priorities::NO_PRIORITY, + 'Priority: normal' => Priorities::NORMAL_PRIORITY, + 'xyz-priority: high' => Priorities::HIGH_PRIORITY, + 'Priority: high' => Priorities::HIGH_PRIORITY, + 'priority: low' => Priorities::LOW_PRIORITY, + 'x-priority: 1000' => Priorities::HIGH_PRIORITY, // only matches first 1, not the full 1000 + 'priority: 3' => Priorities::NORMAL_PRIORITY, + 'IPM-Importance: low' => Priorities::LOW_PRIORITY, + 'My-Importance: URGENT' => Priorities::HIGH_PRIORITY, + 'Urgency: High' => Priorities::NO_PRIORITY, //urgency doesn't match.. maybe it should? + 'Importance: Low' => Priorities::LOW_PRIORITY, + 'X-MSMail-Priority: High' => Priorities::HIGH_PRIORITY, + '' => Priorities::NO_PRIORITY + ) as $priority => $response ) { + $this->assert(is_int($response), "Setup fail, function should only return Integer values"); + //get header + $header = $this->h($priority); + + if(strlen($priority)){ + $this->assert((strlen($header) > $strlen_base), "Setup fail, function h not returning correct string length"); + } + if (! (call_user_func_array ($func_class_method , array($header) ) == $response)){ + //TODO: make line number dynamic + $this->fail ( "class.mailparse.php", 351, "Algorithm mistake: $priority should return $response!" ); + }else{ + $this->pass(); + } + } - foreach ( array ( - 'X-Priority: isNAN' => Priorities::NO_PRIORITY, // input => output - 'X-Priority: 1' => Priorities::LOW_PRIORITY, - 'X-Priority: 2' => Priorities::LOW_PRIORITY, - 'X-Priority: 3' => Priorities::NORMAL_PRIORITY, - 'X-Priority: 4' => Priorities::NORMAL_PRIORITY, - 'X-Priority: 5' => Priorities::HIGH_PRIORITY, - 'X-Priority: 6' => Priorities::HIGH_PRIORITY, - 'No priority set' => Priorities::NO_PRIORITY, - 'Priority: normal' => Priorities::NORMAL_PRIORITY, - 'xyz-priority: high' => Priorities::HIGH_PRIORITY, - 'Priority: high' => Priorities::HIGH_PRIORITY, - 'priority: low' => Priorities::LOW_PRIORITY, - 'x-priority: 1000' => Priorities::LOW_PRIORITY, // only matches first 1, not the full 1000 - 'priority: 3' => Priorities::NORMAL_PRIORITY, - 'IPM-Importance: low' => Priorities::LOW_PRIORITY, - 'My-Importance: URGENT' => Priorities::HIGH_PRIORITY, - 'Urgency: High' => Priorities::NO_PRIORITY, //urgency doesn't match.. maybe it should? - 'X-Importance: 5' => Priorities::HIGH_PRIORITY, - '' => Priorities::NO_PRIORITY - ) as $priority => $response ) { - $this->assert(is_int($response), "Setup fail, function should only return Integer values"); - //get header - $header = $this->h($priority); - - if(strlen($priority)){ - $this->assert((strlen($header) > $strlen_base), "Setup fail, function h not returning correct string length"); - } - if (! (call_user_func_array ($func_class_method , array($header) ) == $response)){ - //TODO: make line number dynamic - $this->fail ( "class.mailparse.php", 351, "Algorithm mistake: $priority should return $response!" ); - }else{ - $this->pass(); - } - } - } - + /** * Generate some header text to test with. Allows insertion of a known header variable - * + * * @param string $setPriority * @return string */ function h($setPriority = "") { - return <<<HEADER + return <<<HEADER Delivered-To: clonemeagain@gmail.com Received: by 10.69.18.42 with SMTP id gj10csp88238pbd; Fri, 20 Dec 2013 10:08:25 -0800 (PST)