Properly capitalizes names.
authorStéphane Jacob <sj@m4x.org>
Sun, 20 Nov 2011 22:51:24 +0000 (23:51 +0100)
committerStéphane Jacob <sj@m4x.org>
Mon, 28 Nov 2011 14:05:30 +0000 (15:05 +0100)
Signed-off-by: Stéphane Jacob <sj@m4x.org>
include/name.func.inc.php
modules/admin.php
modules/profile/general.inc.php
modules/xnet.php
modules/xnetgrp.php

index 6483449..44296c2 100644 (file)
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
  ***************************************************************************/
 
+// Some particles should not be capitalized (cf "ORTHOTYPO", by Jean-Pierre
+// Lacroux).
+// Note that some of them are allowed to use capital letters in some cases,
+// for instance "De" in American English.
+static $particles = array('d', 'de', 'an', 'auf', 'von', 'von dem',
+                          'von der', 'zu', 'of', 'del', 'de las',
+                          'de les', 'de los', 'las', 'los', 'y', 'a',
+                          'da', 'das', 'do', 'dos', 'af', 'av');
+
+
 function build_javascript_names($data, $isFemale)
 {
     $names = array();
@@ -201,5 +211,51 @@ function update_public_names($pid, array $public_names)
                  $public_names['firstname_main'], $public_names['firstname_ordinary'], $public_names['pseudonym'], $pid);
 }
 
+// Returns the @p name with all letters in lower case, but the first one.
+function mb_ucfirst($name)
+{
+    return mb_strtoupper(mb_substr($name, 0, 1)) . mb_substr($name, 1);
+}
+
+// Capitalizes the @p name using French typographic rules. Returns
+// false when capitalization rule is not known for the name format.
+function capitalize_name($name)
+{
+    // Some suffixes should not be captitalized either, eg 's' in Bennett's.
+    static $suffixes = array('h', 's', 't');
+
+    // Extracts the first token of the name.
+    if (!preg_match('/^(\pL+)(([\' -])(.*))?$/ui', $name, $m)) {
+        return false;
+    }
+
+    $token = mb_strtolower($m[1]);
+    $separator = (isset($m[3]) ? $m[3] : false);
+    $tail = (isset($m[4]) ? $m[4] : false);
+
+    // Special case for "Malloc'h".
+    if ($separator == "'" && in_array(strtolower($tail[0]), $suffixes) &&
+        (strlen($tail) == 1 || $tail[1] == ' ')) {
+        $token .= "'" . strtolower($tail[0]);
+        $separator = (strlen($tail) == 1 ? false : $tail[1]);
+        $tail = (strlen($tail) > 2 ? substr($tail, 2) : false);
+    }
+
+    // Capitalizes the first token.
+    if (!in_array($token, $particles)) {
+        $token = mb_ucfirst($token);
+    }
+
+    // Capitalizes the tail of the name.
+    if ($tail) {
+        if (($tail = capitalize_name($tail))) {
+            return $token . $separator . $tail;
+        }
+        return false;
+    }
+
+    return $token . $separator;
+}
+
 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
 ?>
index 7f86769..8a53ba4 100644 (file)
@@ -451,22 +451,25 @@ class AdminModule extends PLModule
             $to_update['weak_password'] = null;
         } else if (Post::has('update_account')) {
             if (!$user->hasProfile()) {
+                require_once 'name.func.inc.php';
                 $name_update = false;
-                if (Post::s('lastname') != $user->lastname) {
-                    $to_update['lastname'] = Post::s('lastname');
+                $lastname = capitalize_name(Post::t('lastname'));
+                $firstname = capitalize_name(Post::t('firstname'));
+                if ($lastname != $user->lastname) {
+                    $to_update['lastname'] = $lastname;
                     $name_update = true;
                 }
-                if (Post::s('type') != 'virtual' && Post::s('firstname') != $user->firstname) {
-                    $to_update['firstname'] = Post::s('firstname');
+                if (Post::s('type') != 'virtual' && $firstname != $user->firstname) {
+                    $to_update['firstname'] = $firstname;
                     $name_update = true;
                 }
                 if ($name_update) {
                     if (Post::s('type') != 'virtual') {
-                        $to_update['full_name'] = Post::s('firstname') . ' ' . Post::s('lastname');
-                        $to_update['directory_name'] = mb_strtoupper(Post::s('lastname')) . ' ' . Post::s('firstname');
+                        $to_update['full_name'] = $firstname . ' ' . $lastname;
+                        $to_update['directory_name'] = $lastname . ' ' . $firstname;
                     } else {
-                        $to_update['full_name'] = Post::s('lastname');
-                        $to_update['directory_name'] = mb_strtoupper(Post::s('lastname'));
+                        $to_update['full_name'] = $lastname;
+                        $to_update['directory_name'] = $lastname;
                     }
                 }
                 if (Post::s('display_name') != $user->displayName()) {
@@ -812,6 +815,7 @@ class AdminModule extends PLModule
 
     function handler_add_accounts($page, $action = null, $promo = null)
     {
+        require_once 'name.func.inc.php';
         $page->changeTpl('admin/add_accounts.tpl');
 
         if (Env::has('add_type') && Env::has('people')) {
@@ -859,9 +863,11 @@ class AdminModule extends PLModule
                 foreach ($lines as $line) {
                     if ($infos = self::formatNewUser($page, $line, $separator, $hrpromo, 6)) {
                         $sex = self::formatSex($page, $infos[3], $line);
+                        $lastname = capitalize_name($infos[0]);
+                        $firstname = capitalize_name($infos[1]);
                         if (!is_null($sex)) {
-                            $fullName = $infos[1] . ' ' . $infos[0];
-                            $directoryName = $infos[0] . ' ' . $infos[1];
+                            $fullName = $firstname . ' ' . $lastname;
+                            $directoryName = $lastname . ' ' . $firstname;
                             $birthDate = self::formatBirthDate($infos[2]);
                             if ($type == 'x') {
                                 $xorgId = Profile::getXorgId($infos[4]);
@@ -882,11 +888,11 @@ class AdminModule extends PLModule
                             $pid = XDB::insertId();
                             XDB::execute('INSERT INTO  profile_public_names (pid, lastname_initial, lastname_main, firstname_initial, firstname_main)
                                                VALUES  ({?}, {?}, {?}, {?}, {?})',
-                                         $pid, $infos[0], $infos[0], $infos[1], $infos[1]);
+                                         $pid, $lastname, $lastname, $firstname, $firstname);
                             XDB::execute('INSERT INTO  profile_display (pid, yourself, public_name, private_name,
                                                                         directory_name, short_name, sort_name, promo)
                                                VALUES  ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})',
-                                         $pid, $infos[1], $fullName, $fullName, $directoryName, $fullName, $directoryName, $promo);
+                                         $pid, $firstname, $fullName, $fullName, $directoryName, $fullName, $directoryName, $promo);
                             XDB::execute('INSERT INTO  profile_education (id, pid, eduid, degreeid, entry_year, grad_year, promo_year, flags)
                                                VALUES  (100, {?}, {?}, {?}, {?}, {?}, {?}, \'primary\')',
                                          $pid, $eduSchools[Profile::EDU_X], $degreeid, $entry_year, $grad_year, $promotion);
@@ -894,7 +900,7 @@ class AdminModule extends PLModule
                                                                  display_name, lastname, firstname, sex, best_domain)
                                                VALUES  ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})',
                                          $infos['hrid'], $type, 0, 'pending', $fullName, $directoryName,
-                                         $infos[1], $infos[0], $infos[1], $sex, $best_domain);
+                                         $firstname, $lastname, $firstname, $sex, $best_domain);
                             $uid = XDB::insertId();
                             XDB::execute('INSERT INTO  account_profiles (uid, pid, perms)
                                                VALUES  ({?}, {?}, {?})',
@@ -911,14 +917,16 @@ class AdminModule extends PLModule
                     if ($infos = self::formatNewUser($page, $line, $separator, $type, 4)) {
                         $sex = self::formatSex($page, $infos[3], $line);
                         if (!is_null($sex)) {
-                            $fullName = $infos[1] . ' ' . $infos[0];
-                            $directoryName = $infos[0] . ' ' . $infos[1];
+                            $lastname = capitalize_name($infos[0]);
+                            $firstname = capitalize_name($infos[1]);
+                            $fullName = $firstname . ' ' . $lastname;
+                            $directoryName = $lastname . ' ' . $firstname;
                             XDB::execute('INSERT INTO  accounts (hruid, type, is_admin, state, email, full_name, directory_name,
                                                                  display_name, lastname, firstname, sex)
                                                VALUES  ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})',
                                          $infos['hrid'], $type, 0, 'pending', $infos[2], $fullName, $directoryName,
-                                         $infos[1], $infos[0], $infos[1], $sex);
-                            $newAccounts[$infos['hrid']] = $infos[1] . ' ' . $infos[0];
+                                         $firstname, $lastname, $firstname, $sex);
+                            $newAccounts[$infos['hrid']] = $fullName;
                         }
                     }
                 }
index f382e7b..11bca46 100644 (file)
@@ -63,6 +63,7 @@ class ProfileSettingSearchNames implements ProfileSetting
 
     public function value(ProfilePage $page, $field, $value, &$success)
     {
+        require_once 'name.func.inc.php';
         $success = true;
 
         if (is_null($value)) {
@@ -94,7 +95,7 @@ class ProfileSettingSearchNames implements ProfileSetting
                                                          $page->pid());
         } else {
             foreach ($value['public_names'] as $key => $name) {
-                $value['public_names'][$key] = trim($name);
+                $value['public_names'][$key] = capitalize_name(trim($name));
             }
             if (isset($value['private_names'])) {
                 foreach ($value['private_names'] as $key => $name) {
@@ -110,7 +111,6 @@ class ProfileSettingSearchNames implements ProfileSetting
             }
         }
 
-        require_once 'name.func.inc.php';
         $public_name = build_first_name($value['public_names']) . ' ' . build_full_last_name($value['public_names'], $page->profile->isFemale());
         if (isset($value['private_names'])) {
             $private_name_end = build_private_name($value['private_names']);
index 9f7e6b3..cb3e7f6 100644 (file)
@@ -250,9 +250,14 @@ class XnetModule extends PLModule
                 }
             }
 
+            require_once 'emails.inc.php';
+            require_once 'name.func.inc.php';
+
             // Update user info
-            $full_name = Post::t('firstname') . ' ' . Post::t('lastname');
-            $directory_name = mb_strtoupper(Post::t('lastname')) . ' ' . Post::t('firstname');
+            $lastname = capitalize_name(Post::t('lastname'));
+            $firstname = capitalize_name(Post::t('firstname'));
+            $full_name = $firstname . ' ' . $lastname;
+            $directory_name = $lastname . ' ' . $firstname;
             XDB::query('UPDATE  accounts
                            SET  full_name = {?}, directory_name = {?}, display_name = {?},
                                 firstname = {?}, lastname = {?}, sex = {?}
@@ -262,7 +267,6 @@ class XnetModule extends PLModule
                        (Post::t('sex') == 'male') ? 'male' : 'female', $user->id());
 
             // Updates email.
-            require_once 'emails.inc.php';
             $new_email = strtolower(Post::t('email'));
             if (require_email_update($user, $new_email)) {
                     XDB::query('UPDATE  accounts
index 47f4a8d..6277582 100644 (file)
@@ -946,16 +946,17 @@ class XnetGrpModule extends PLModule
 
                 // If the user has no account yet, creates new account: build names from email address.
                 if (empty($user)) {
+                    require_once 'name.func.inc.php';
                     $parts = explode('.', $mbox);
                     if (count($parts) == 1) {
-                        $lastname = $display_name = $full_name = $directory_name = ucfirst($mbox);
+                        $lastname = $display_name = $full_name = $directory_name = capitalize_name($mbox);
                         $firstname = '';
                     } else {
-                        $firstname = ucfirst($parts[0]);
-                        $lastname = ucwords(implode(' ', array_slice($parts, 1)));
+                        $firstname = capitalize_name($parts[0]);
+                        $lastname = capitalize_name(implode(' ', array_slice($parts, 1)));
                         $display_name = $firstname;
-                        $full_name = "$firstname $lastname";
-                        $directory_name = strtoupper($lastname) . " " . $firstname;
+                        $full_name = $firstname . ' ' . $lastname;
+                        $directory_name = $lastname . ' ' . $firstname;
                     }
                     XDB::execute('INSERT INTO  accounts (hruid, display_name, full_name, directory_name, firstname, lastname, email, type, state)
                                        VALUES  ({?}, {?}, {?}, {?}, {?}, {?}, {?}, \'xnet\', \'disabled\')',
@@ -1247,15 +1248,15 @@ class XnetGrpModule extends PLModule
 
             // Update user info
             if ($user->type == 'virtual' || ($user->type == 'xnet' && !$user->perms)) {
-                $lastname = Post::s('lastname');
+                $lastname = capitalize_name(Post::t('lastname'));
                 if (Post::s('type') != 'virtual') {
-                    $firstname = Post::s('firstname');
+                    $firstname = capitalize_name(Post::t('firstname'));
                     $full_name = $firstname . ' ' . $lastname;
-                    $directory_name = mb_strtoupper($lastname) . ' ' . $firstname;
+                    $directory_name = $lastname . ' ' . $firstname;
                 } else {
                     $firstname = '';
                     $full_name = $lastname;
-                    $directory_name = mb_strtoupper($lastname);
+                    $directory_name = $lastname;
                 }
                 XDB::query('UPDATE  accounts
                                SET  full_name = {?}, directory_name = {?}, display_name = {?},