From 6199e24eaa7a8674f3cc70484b1f8c6dcb6aa2bb Mon Sep 17 00:00:00 2001
From: Jared Hancock <jared@osticket.com>
Date: Wed, 6 Nov 2013 04:23:39 +0000
Subject: [PATCH] Handle email addresses used as names

If an email arrives in the system without a "personal" field (name), the
email address is used as the name. The email address, however, is not parsed
well by the PersonsName constructor. This patch uses the mailbox of the
email address as the name.

Also include a slight boost to the mbstring compatibility functions declared
in the bootstrap::i18n_prep() function
---
 bootstrap.php          | 40 +++++++++++++++++++++++++++++++++++++---
 include/class.user.php | 11 +++++++++++
 2 files changed, 48 insertions(+), 3 deletions(-)

diff --git a/bootstrap.php b/bootstrap.php
index cc9437d7c..b303616ff 100644
--- a/bootstrap.php
+++ b/bootstrap.php
@@ -203,15 +203,49 @@ class Bootstrap {
                 function mb_strlen($str) { return strlen($str); }
                 function mb_substr($a, $b, $c=null) { return substr($a, $b, $c); }
                 function mb_convert_encoding($str, $to, $from='utf-8') {
-                    return iconv($from, $to, $str); }
+                    if (strcasecmp($to, $from) == 0)
+                        return $str;
+                    elseif (in_array(strtolower($to), array(
+                            'us-ascii','latin-1','iso-8859-1'))
+                            && function_exists('utf8_encode'))
+                        return utf8_encode($str);
+                    else
+                        return $str;
+                }
+            }
+            define('LATIN1_UC_CHARS', 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝ');
+            define('LATIN1_LC_CHARS', 'àáâãäåæçèéêëìíîïðñòóôõöøùúûüý');
+            function mb_strtoupper($a) {
+                return strtoupper(strtr($str, LATIN1_LC_CHARS, LATIN1_UC_CHARS));
+            }
+            function mb_strtolower($a) {
+                return strtolower(strtr($str, LATIN1_UC_CHARS, LATIN1_LC_CHARS));
+            }
+            define('MB_CASE_LOWER', 1);
+            define('MB_CASE_UPPER', 2);
+            define('MB_CASE_TITLE', 3);
+            function mb_convert_case($str, $mode) {
+                // XXX: Techincally the calls to strto...() will fail if the
+                //      char is not a single-byte char
+                switch ($mode) {
+                case MB_CASE_LOWER:
+                    return preg_replace_callback('/\p{Lu}+/u',
+                        function($a) { return mb_strtolower($a); }, $str);
+                case MB_CASE_UPPER:
+                    return preg_replace_callback('/\p{Ll}+/u',
+                        function($a) { return mb_strtoupper($a); }, $str);
+                case MB_CASE_TITLE:
+                    return preg_replace_callback('/\b\p{Ll}/u',
+                        function($a) { return mb_strtoupper($a); }, $str);
+                }
             }
-            function mb_strtoupper($a) { return strtoupper($a); }
-            function mb_strtolower($a) { return strtolower($a); }
         }
         else {
             // Use UTF-8 for all multi-byte string encoding
             mb_internal_encoding('utf-8');
         }
+        if (extension_loaded('iconv'))
+            iconv_set_encoding('internal_encoding', 'UTF-8');
     }
 
     function croak($message) {
diff --git a/include/class.user.php b/include/class.user.php
index b1aae2e7c..c89543f2b 100644
--- a/include/class.user.php
+++ b/include/class.user.php
@@ -159,6 +159,17 @@ class User extends UserModel {
                 $this->name = $parts[1].' '.$parts[0].' '.$parts[2];
                 break;
         }
+
+        // Handle email addresses -- use the box name
+        if (Validator::is_email($this->name)) {
+            list($box, $domain) = explode('@', $this->name, 2);
+            if (strpos($box, '.') !== false)
+                $this->name = str_replace('.', ' ', $box);
+            else
+                $this->name = $box;
+            $this->name = mb_convert_case($this->name, MB_CASE_TITLE);
+        }
+
         if (count($this->dirty))
             $this->set('updated', new SqlFunction('NOW'));
         return parent::save($refetch);
-- 
GitLab