Simplifies profile names handling.
authorStéphane Jacob <sj@m4x.org>
Tue, 24 May 2011 13:45:51 +0000 (15:45 +0200)
committerStéphane Jacob <sj@m4x.org>
Sat, 28 May 2011 12:43:09 +0000 (14:43 +0200)
Signed-off-by: Stéphane Jacob <sj@m4x.org>
19 files changed:
bin/export_sql.bash
classes/direnum.php
classes/profile.php
htdocs/javascript/profile.js
include/name.func.inc.php
include/validations/names.inc.php
include/webservices/manageurs.server.inc.php
modules/admin.php
modules/profile.php
modules/profile/general.inc.php
modules/register.php
templates/admin/index.tpl
templates/include/form.valid.names.tpl
templates/profile/general.private_name.tpl [new file with mode: 0644]
templates/profile/general.public_names.tpl [new file with mode: 0644]
templates/profile/general.searchname.tpl [deleted file]
templates/profile/general.tpl
upgrade/1.1.2/03_names.sql [new file with mode: 0644]
upgrade/1.1.2/README [new file with mode: 0644]

index 2ecc94f..ac2d9b7 100755 (executable)
@@ -27,7 +27,6 @@ profile_job_term_relation \
 profile_langskill_enum \
 profile_medal_enum \
 profile_medal_grade_enum \
-profile_name_enum \
 profile_networking_enum \
 profile_section_enum \
 profile_skill_enum \
index 1962d28..16cdb25 100644 (file)
@@ -29,9 +29,6 @@ class DirEnum
      * Each of these consts contains the basename of the class (its full name
      * being DE_$basename).
      */
-    const NAMETYPES      = 'nametypes';
-    const NAMES          = 'names';
-
     const BINETS         = 'binets';
     const GROUPESX       = 'groupesx';
     const SECTIONS       = 'sections';
@@ -433,29 +430,6 @@ abstract class DE_WithSuboption extends DirEnumeration
 }
 // }}}
 
-// {{{ class DE_NameTypes
-// returns 'system' names ('lastname', 'lastname_marital', ...)
-class DE_NameTypes extends DirEnumeration
-{
-    public $capabilities = 0x005; // self::HAS_OPTIONS | self::SAVE_IN_SESSION;
-
-    protected $from     = 'profile_name_enum';
-    protected $valfield = 'type';
-}
-// }}}
-
-// {{{ class DE_Names
-// returns 'system' names ('lastname', 'lastname_marital', ...)
-class DE_Names extends DirEnumeration
-{
-    public $capabilities = 0x005; // self::HAS_OPTIONS | self::SAVE_IN_SESSION;
-
-    protected $from     = 'profile_name_enum';
-    protected $idfield  = 'type';
-    protected $valfield = 'name';
-}
-// }}}
-
 /** GROUPS
  */
 // {{{ class DE_Binets
index 177155a..988c1c6 100644 (file)
@@ -427,7 +427,7 @@ class Profile implements PlExportable
      *      profile_job, profile_langskills, profile_mentor, profile_networking,
      *      profile_phones, profile_skills, watch_profile
      *  *always keeps in: profile_corps, profile_display, profile_education,
-     *      profile_medals, profile_name, profile_photos, search_name
+     *      profile_medals, profile_*_names, profile_photos, search_name
      *  *modifies: profiles
      */
     public function clear()
@@ -947,10 +947,9 @@ class Profile implements PlExportable
                                      IF (p.freetext_pub IN {?}, p.freetext, NULL) AS freetext,
                                      pe.entry_year, pe.grad_year, pe.promo_year, pe.program, pe.fieldid,
                                      IF ({?}, pse.text, NULL) AS section,
-                                     pn_f.name AS firstname, pn_l.name AS lastname,
-                                     IF ({?}, pn_n.name, NULL) AS nickname,
-                                     IF (pn_uf.name IS NULL, pn_f.name, pn_uf.name) AS firstname_ordinary,
-                                     IF (pn_ul.name IS NULL, pn_l.name, pn_ul.name) AS lastname_ordinary,
+                                     ppn.firstname_main AS firstname, ppn.lastname_main AS lastname, IF ({?}, pn.name, NULL) AS nickname,
+                                     IF (ppn.firstname_ordinary = \'\', ppn.firstname_main, ppn.firstname_ordinary) AS firstname_ordinary,
+                                     IF (ppn.lastname_ordinary = \'\', ppn.firstname_main, ppn.lastname_ordinary) AS lastname_ordinary,
                                      pd.yourself, pd.promo, pd.short_name, pd.public_name AS full_name,
                                      pd.directory_name, pd.public_name, pd.private_name,
                                      IF (pp.pub IN {?}, pp.display_tel, NULL) AS mobile,
@@ -964,16 +963,8 @@ class Profile implements PlExportable
                          INNER JOIN  profile_display AS pd ON (pd.pid = p.pid)
                          INNER JOIN  profile_education AS pe ON (pe.pid = p.pid AND FIND_IN_SET(\'primary\', pe.flags))
                           LEFT JOIN  profile_section_enum AS pse ON (pse.id = p.section)
-                         INNER JOIN  profile_name AS pn_f ON (pn_f.pid = p.pid
-                                                              AND pn_f.typeid = ' . self::getNameTypeId('firstname', true) . ')
-                         INNER JOIN  profile_name AS pn_l ON (pn_l.pid = p.pid
-                                                              AND pn_l.typeid = ' . self::getNameTypeId('lastname', true) . ')
-                          LEFT JOIN  profile_name AS pn_uf ON (pn_uf.pid = p.pid
-                                                               AND pn_uf.typeid = ' . self::getNameTypeId('firstname_ordinary', true) . ')
-                          LEFT JOIN  profile_name AS pn_ul ON (pn_ul.pid = p.pid
-                                                               AND pn_ul.typeid = ' . self::getNameTypeId('lastname_ordinary', true) . ')
-                          LEFT JOIN  profile_name AS pn_n ON (pn_n.pid = p.pid
-                                                              AND pn_n.typeid = ' . self::getNameTypeId('nickname', true) . ')
+                         INNER JOIN  profile_public_names AS ppn ON (ppn.pid = p.pid)
+                          LEFT JOIN  profile_private_names AS pn ON (pn.pid = p.pid AND type = \'nickname\')
                           LEFT JOIN  profile_phones AS pp ON (pp.pid = p.pid AND pp.link_type = \'user\' AND tel_type = \'mobile\')
                           LEFT JOIN  profile_photos AS ph ON (ph.pid = p.pid)
                           LEFT JOIN  profile_mentor AS pm ON (pm.pid = p.pid)
@@ -1115,47 +1106,46 @@ class Profile implements PlExportable
         }
     }
 
-    public static function getNameTypeId($type, $for_sql = false)
-    {
-        if (!S::has('name_types')) {
-            $table = XDB::fetchAllAssoc('type', 'SELECT  id, type
-                                                   FROM  profile_name_enum');
-            S::set('name_types', $table);
-        } else {
-            $table = S::v('name_types');
-        }
-        if ($for_sql) {
-            return XDB::escape($table[$type]);
-        } else {
-            return $table[$type];
-        }
-    }
-
     public static function rebuildSearchTokens($pids, $transaction = true)
     {
+        require_once 'name.func.inc.php';
         if (!is_array($pids)) {
             $pids = array($pids);
         }
-        $keys = XDB::iterator("(SELECT  n.pid AS pid, n.name AS name, e.score AS score, e.general_type,
-                                        IF(FIND_IN_SET('public', e.flags), 'public', '') AS public
-                                  FROM  profile_name      AS n
-                            INNER JOIN  profile_name_enum AS e ON (n.typeid = e.id)
-                                 WHERE  n.pid IN {?} AND NOT FIND_IN_SET('not_displayed', e.flags))
-                                 UNION
-                                (SELECT  n.pid AS pid, n.particle AS name, 0 AS score, e.general_type,
-                                         IF(FIND_IN_SET('public', e.flags), 'public', '') AS public
-                                   FROM  profile_name      AS n
-                             INNER JOIN  profile_name_enum AS e ON (n.typeid = e.id)
-                                  WHERE  n.pid IN {?} AND NOT FIND_IN_SET('not_displayed', e.flags))
-                               ",
-                              $pids, $pids);
+        $keys = XDB::iterator("(SELECT  pid, name, type, IF(type = 'nickname', 2, 1) AS score, '' AS public
+                                  FROM  profile_private_names
+                                 WHERE  pid IN {?})
+                                UNION
+                               (SELECT  pid, lastname_main, 'lastname' AS type, 10 AS score, 'public' AS public
+                                  FROM  profile_public_names
+                                 WHERE  lastname_main != '' AND pid IN {?})
+                                UNION
+                               (SELECT  pid, lastname_marital, 'lastname' AS type, 10 AS score, 'public' AS public
+                                  FROM  profile_public_names
+                                 WHERE  lastname_marital != '' AND pid IN {?})
+                                UNION
+                               (SELECT  pid, lastname_ordinary, 'lastname' AS type, 10 AS score, 'public' AS public
+                                  FROM  profile_public_names
+                                 WHERE  lastname_ordinary != '' AND pid IN {?})
+                                UNION
+                               (SELECT  pid, firstname_main, 'firstname' AS type, 10 AS score, 'public' AS public
+                                  FROM  profile_public_names
+                                 WHERE  firstname_main != '' AND pid IN {?})
+                                UNION
+                               (SELECT  pid, firstname_ordinary, 'firstname' AS type, 10 AS score, 'public' AS public
+                                  FROM  profile_public_names
+                                 WHERE  firstname_ordinary != '' AND pid IN {?})
+                                UNION
+                               (SELECT  pid, pseudonym, 'nickname' AS type, 10 AS score, 'public' AS public
+                                  FROM  profile_public_names
+                                 WHERE  pseudonym != '' AND pid IN {?})",
+                              $pids, $pids, $pids, $pids, $pids, $pids, $pids);
         $names = array();
         while ($key = $keys->next()) {
             if ($key['name'] == '') {
                 continue;
             }
-            $pid   = $key['pid'];
-            require_once 'name.func.inc.php';
+            $pid  = $key['pid'];
             $toks = split_name_for_search($key['name']);
             $toks = array_reverse($toks);
 
@@ -1170,7 +1160,7 @@ class Profile implements PlExportable
                 $token = $tok . $token;
                 $names["$pid-$token"] = XDB::format('({?}, {?}, {?}, {?}, {?}, {?})',
                                                     $token, $pid, soundex_fr($token),
-                                                    $eltScore, $key['public'], $key['general_type']);
+                                                    $eltScore, $key['public'], $key['type']);
             }
         }
         if ($transaction) {
index d4899ec..2057e69 100644 (file)
@@ -77,12 +77,10 @@ function addSearchName(isFemale)
     while ($('#search_name_' + i).length != 0) {
         i++;
     }
-    $('#search_name_' + i)
-        .updateHtml('profile/ajax/searchname/' + i + '/' + isFemale,
-                    function(data) {
-                        $('#searchname').before(data);
-                        changeNameFlag(i);
-                    });
+    $('#search_name_' + i).updateHtml('profile/ajax/searchname/' + i + '/' + isFemale,
+        function(data) {
+            $('#searchname').before(data);
+    });
 }
 
 function removeSearchName(i, isFemale)
@@ -91,34 +89,29 @@ function removeSearchName(i, isFemale)
     updateNameDisplay(isFemale);
 }
 
-function changeNameFlag(i)
-{
-    $('#flag_' + i).remove();
-    var typeid = $('#search_name_' + i).find('select').val();
-    var type   = $('#search_name_' + i).find('select :selected').text();
-    if ($('[name=sn_type_' + typeid + '_' + i + ']').val() > 0) {
-        $('#flag_cb_' + i).after('<span id="flag_' + i + '">&nbsp;' +
-            '<img src="images/icons/flag_green.gif" alt="site public" title="site public" />' +
-            '<input type="hidden" name="search_names[' + i + '][pub]" value="1"/>' +
-            '<input type="hidden" name="search_names[' + i + '][typeid]" value="' + typeid + '"/>' +
-            '<input type="hidden" name="search_names[' + i + '][type]" value="' + type + '"/></span>');
-    } else {
-        $('#flag_cb_' + i).after('<span id="flag_' + i + '">&nbsp;' +
-            '<img src="images/icons/flag_red.gif" alt="site privé" title="site privé" />' +
-            '<input type="hidden" name="search_names[' + i + '][typeid]" value="' + typeid + '"/>' +
-            '<input type="hidden" name="search_names[' + i + '][type]" value="' + type + '"/></span>');
-    }
-}
-
 function updateNameDisplay(isFemale)
 {
+    var lastnames = new Array('lastname_main', 'lastname_ordinary', 'lastname_marital', 'pseudonym');
+    var firstnames = new Array('firstname_main', 'firstname_ordinary');
     var searchnames = '';
-    for (var i = 0; i < 10; i++) {
+
+    for (var i = 0; i < 4; ++i) {
+        searchnames += $('.names_advanced').find('[name*=' + lastnames[i] + ']').val() + ';';
+    }
+    searchnames += '-;'
+    for (var i = 0; i < 2; ++i) {
+        searchnames += $('.names_advanced').find('[name*=' + firstnames[i] + ']').val() + ';';
+    }
+    searchnames += '-';
+
+    var has_private = false;
+    for (var i = 0; i < 10; ++i) {
         if ($('#search_name_' + i).find(':text').val()) {
-            searchnames += $('#search_name_' + i).find('[name*=typeid]').val() + ';';
-            searchnames += $('#search_name_' + i).find(':text').val() + ';;';
+            searchnames += ';' + $('#search_name_' + i).find('[name*=type]').val() + ';' + $('#search_name_' + i).find(':text').val();
+            has_private = true;
         }
     }
+    searchnames += (has_private ? '' : ';');
     $.xget('profile/ajax/buildnames/' + searchnames + '/' + isFemale,
            function(data){
                var name = data.split(';');
@@ -127,15 +120,6 @@ function updateNameDisplay(isFemale)
            });
 }
 
-function toggleParticle(id)
-{
-    if ($('#search_name_' + id).find("[name*='[particle]']").val() == '') {
-        $('#search_name_' + id).find("[name*='[particle]']").val(1);
-    } else {
-        $('#search_name_' + id).find("[name*='[particle]']").val('');
-    }
-}
-
 // Promotions {{{1
 
 function togglePromotionEdition()
index 1f78daf..6483449 100644 (file)
 
 function build_javascript_names($data, $isFemale)
 {
-    $data_array = explode(';;', $data);
-    $n = count($data_array);
-    $n--;
-    for ($i = 0; $i < $n; $i++) {
-        $searchname = explode(';', $data_array[$i]);
-        if (isset($search_names[$searchname[0]])) {
-            $search_names[$searchname[0]][] = $searchname[1];
-        } else {
-            $search_names[$searchname[0]] = array('fullname' => $searchname[1]);
-        }
-    }
+    $names = array();
+    foreach (explode(';-;', $data) as $key => $item) {
+        $names[$key] = explode(';', $item);
+    }
+    $lastnames = array(
+        'lastname_main'     => $names[0][0],
+        'lastname_ordinary' => $names[0][1],
+        'lastname_marital'  => $names[0][2],
+        'pseudonym'         => $names[0][3]
+    );
+    $firstnames = array(
+        'firstname_main'     => $names[1][0],
+        'firstname_ordinary' => $names[1][1]
+    );
+    $private_names_count = intval(count($names[2]) / 2);
+    $private_names = array();
+    for ($i = 0; $i < $private_names_count; ++$i) {
+        $private_names[] = array('type' => $names[2][2 * $i], 'name' => $names[2][2 * $i + 1]);
+    }
+
+    return build_first_name($firstnames) . ' ' . build_full_last_name($lastnames, $isFemale) . ';' . build_private_name($private_names);
+}
 
-    $sn_types_public  = build_types('public');
-    $sn_types_private = build_types('private');
-    $full_name        = build_full_name($search_names, $sn_types_public, $isFemale);
-    return build_public_name($search_names, $sn_types_public, $full_name) . ';' .
-           build_private_name($search_names, $sn_types_private);
+function build_email_alias(array $public_names)
+{ 
+    return PlUser::makeUserName(build_first_name($public_names), build_short_last_name($public_names));
 }
 
-function build_display_names(&$display_names, $search_names, $isFemale, $private_name_end = null, &$alias = null)
+function build_display_names(array $public_names, array $private_names, $isFemale)
 {
-    $sn_types_public  = build_types('public');
-    $full_name        = build_full_name($search_names, $sn_types_public, $isFemale);
-    $display_names['public_name']    = build_public_name($search_names, $sn_types_public, $full_name);
-    $display_names['private_name']   = $display_names['public_name'] . $private_name_end;
-    $display_names['directory_name'] = build_directory_name($search_names, $sn_types_public, $full_name);
-    $display_names['short_name']     = build_short_name($search_names, $sn_types_public, $alias);
-    $display_names['sort_name']      = build_sort_name($search_names, $sn_types_public);
+    $short_last_name = build_short_last_name($public_names);
+    $full_last_name = build_full_last_name($public_names, $isFemale);
+    $private_last_name_end = build_private_name($private_names);
+    $firstname = build_first_name($public_names);
+
+    $display_names = array();
+    $display_names['public_name']    = $firstname . ' ' . $full_last_name;
+    $display_names['private_name']   = $display_names['public_name'] . $private_last_name_end;
+    $display_names['directory_name'] = $full_last_name . ' ' . $firstname;
+    $display_names['short_name']     = $firstname . ' ' . $short_last_name;
+    $display_names['sort_name']      = $short_last_name . ' ' . $firstname;
+
+    return $display_names;
 }
 
-function build_types($pub = null)
+function build_short_last_name(array $lastnames)
 {
-    if ($pub == 'public') {
-        $sql_pub = "AND FIND_IN_SET('public', flags)";
-    } elseif ($pub == 'private') {
-        $sql_pub = "AND NOT FIND_IN_SET('public', flags)";
-    } else {
-        $sql_pub = "";
-    }
-    $sql = "SELECT  id, type, name
-              FROM  profile_name_enum
-             WHERE  NOT FIND_IN_SET('not_displayed', flags)" . $sql_pub;
-    $sn_types = XDB::iterator($sql);
-    $types    = array();
-    while ($sn_type = $sn_types->next()) {
-        if ($pub) {
-            $types[$sn_type['type']] = $sn_type['id'];
-        } else {
-            $types[$sn_type['id']]   = $sn_type['name'];
-        }
-    }
-    return $types;
+    return ($lastnames['lastname_ordinary'] == '') ? $lastnames['lastname_main'] : $lastnames['lastname_ordinary'];
 }
 
-function build_full_name(&$search_names, &$sn_types, $isFemale)
+function build_full_last_name(array $lastnames, $isFemale)
 {
-    $name = "";
-    if (isset($search_names[$sn_types['lastname_ordinary']])) {
-        $name .= $search_names[$sn_types['lastname_ordinary']]['fullname'] . " ("
-              . $search_names[$sn_types['lastname']]['fullname'] . ")";
+    if ($lastnames['lastname_ordinary'] != '') {
+        $name = $lastnames['lastname_ordinary'] . ' (' . $lastnames['lastname_main'] . ')';
     } else {
-        $name .= $search_names[$sn_types['lastname']]['fullname'];
+        $name = $lastnames['lastname_main'];
     }
-    if (isset($search_names[$sn_types['lastname_marital']])
-        || isset($search_names[$sn_types['pseudonym']])) {
-        $name .= " (";
-        if (isset($search_names[$sn_types['lastname_marital']])) {
-            if ($isFemale) {
-                $name .= "Mme ";
-            } else {
-                $name .= "M ";
-            }
-            $name .= $search_names[$sn_types['lastname_marital']]['fullname'];
-            if (isset($search_names[$sn_types['pseudonym']])) {
-                $name .= ", ";
-            }
-        }
-        if (isset($search_names[$sn_types['pseudonym']])) {
-            $name .= $search_names[$sn_types['pseudonym']]['fullname'];
+    if ($lastnames['lastname_marital'] != '' || $lastnames['pseudonym'] != '') {
+        $name .= ' (';
+        if ($lastnames['lastname_marital'] != '') {
+            $name .= ($isFemale ? 'Mme ' : 'M ') . $lastnames['lastname_marital'];
+            $name .= (($lastnames['pseudonym'] == '') ? '' : ', ');
         }
-        $name .= ")";
+        $name .= (($lastnames['pseudonym'] == '')? '' : $lastnames['pseudonym']) . ')';
     }
     return $name;
 }
 
-function build_public_name(&$search_names, &$sn_types, $full_name)
+function build_first_name(array $firstnames)
 {
-    return $search_names[$sn_types['firstname']]['fullname'] . " " . $full_name;
+    return ($firstnames['firstname_ordinary'] ? $firstnames['firstname_ordinary'] : $firstnames['firstname_main']);
 }
 
-function build_private_name(&$search_names, &$sn_types)
+function build_private_name(array $private_names)
 {
-    $name = "";
-    if (isset($search_names[$sn_types['nickname']])
-        || (isset($search_names[$sn_types['name_other']])
-        || isset($search_names[$sn_types['name_other']]))) {
-        $name .= " (";
-        if (isset($search_names[$sn_types['nickname']])) {
-            $name .= "alias " . $search_names[$sn_types['nickname']]['fullname'];
-            $i = 0;
-            while (isset($search_names[$sn_types['nickname']][$i])) {
-                $name .= ", " . $search_names[$sn_types['nickname']][$i];
-                $i++;
-            }
-            if (isset($search_names[$sn_types['name_other']])
-                || isset($search_names[$sn_types['firstname_other']])) {
-                $name .= ", ";
-            }
-        }
-        if (isset($search_names[$sn_types['firstname_other']])) {
-            $name .= "autres prénoms : " . $search_names[$sn_types['firstname_other']]['fullname'];
-            $i = 0;
-            while (isset($search_names[$sn_types['firstname_other']][$i])) {
-                $name .= ", " . $search_names[$sn_types['firstname_other']][$i];
-                $i++;
-            }
-            if (isset($search_names[$sn_types['name_other']])) {
-                $name .= ", ";
-            }
-        }
-        if (isset($search_names[$sn_types['name_other']])) {
-            $name .= "autres noms : " . $search_names[$sn_types['name_other']]['fullname'];
-            $i = 0;
-            while (isset($search_names[$sn_types['name_other']][$i])) {
-                $name .= ", " . $search_names[$sn_types['name_other']][$i];
-                $i++;
-            }
-        }
-        $name .= ")";
+    if (is_null($private_names) || count($private_names) == 0) {
+        return '';
     }
-    return $name;
-}
 
-function build_directory_name(&$search_names, &$sn_types, $full_name)
-{
-    return $full_name . " " . $search_names[$sn_types['firstname']]['fullname'];
-}
+    static $types = array('nickname' => 'alias ', 'firstname' => 'autres prénoms : ', 'lastname' => 'autres noms : ');
+    $names_sorted = array('nickname' => array(), 'firstname' => array(), 'lastname' => array());
 
-function build_short_name(&$search_names, &$sn_types, &$alias = null)
-{
-    if (isset($search_names[$sn_types['lastname_ordinary']])) {
-        $lastname = $search_names[$sn_types['lastname_ordinary']]['fullname'];
-    } else {
-        $lastname = $search_names[$sn_types['lastname']]['fullname'];
-    }
-    if (isset($search_names[$sn_types['firstname_ordinary']])) {
-        $firstname = $search_names[$sn_types['firstname_ordinary']]['fullname'];
-    } else {
-        $firstname = $search_names[$sn_types['firstname']]['fullname'];
-    }
-    if ($alias) {
-        $alias = PlUser::makeUserName($firstname, $lastname);
-    }
-    return $firstname . " " . $lastname;
-}
-
-function build_sort_name(&$search_names, &$sn_types)
-{
-    $name = "";
-    if (isset($search_names[$sn_types['lastname_ordinary']])) {
-        $name .= $search_names[$sn_types['lastname_ordinary']]['name'];
-    } else {
-        $name .= $search_names[$sn_types['lastname']]['name'];
+    foreach ($private_names as $private_name) {
+        $names_sorted[$private_name['type']][] = $private_name['name'];
     }
-    $name .= " " . $search_names[$sn_types['firstname']]['fullname'];
-    return $name;
-}
-
-function set_profile_display(&$display_names, Profile $profile)
-{
-    XDB::execute("UPDATE  profile_display
-                     SET  public_name = {?}, private_name = {?},
-                          directory_name = {?}, short_name = {?}, sort_name = {?}
-                   WHERE  pid = {?}",
-                 $display_names['public_name'], $display_names['private_name'],
-                 $display_names['directory_name'], $display_names['short_name'],
-                 $display_names['sort_name'], $profile->id());
 
-    $owner = $profile->owner();
-    if ($owner) {
-        XDB::execute('UPDATE  accounts
-                         SET  full_name = {?}, directory_name = {?}
-                       WHERE  uid = {?}',
-                     $display_names['public_name'], $display_names['directory_name'], $owner->id());
+    $names_array = array();
+    foreach ($names_sorted as $type => $names) {
+        if (count($names)) {
+            $names_array[] = $types[$type] . implode(', ', $names);
+        }
     }
-}
 
-function build_sn_pub($pid)
-{
-    $res = XDB::iterator("SELECT  CONCAT(sn.particle, sn.name) AS fullname, sn.typeid,
-                                  sn.particle, sn.name, sn.id
-                            FROM  profile_name      AS sn
-                      INNER JOIN  profile_name_enum AS e  ON (e.id = sn.typeid)
-                           WHERE  sn.pid = {?} AND NOT FIND_IN_SET('not_displayed', e.flags)
-                                  AND FIND_IN_SET('public', e.flags)
-                        ORDER BY  NOT FIND_IN_SET('always_displayed', e.flags), e.id, sn.name",
-                         $pid);
-    $sn_old = array();
-    while ($old = $res->next()) {
-        $sn_old[$old['typeid']] = array('fullname' => $old['fullname'],
-                                        'name'     => $old['name'],
-                                        'particle' => $old['particle'],
-                                        'id'       => $old['id']);
-    }
-    return $sn_old;
+    return ' (' . implode(', ', $names_array) . ')';
 }
 
 /** Splits a name into tokens, as used in search_name.
@@ -255,94 +144,61 @@ function compare_basename($a, $b) {
     return name_to_basename($a) == name_to_basename($b);
 }
 
-function set_alias_names(&$sn_new, $sn_old, $pid, PlUser $user, $update_new = false, $new_alias = null)
+function update_account_from_profile($uid)
 {
-    $has_new = false;
-    foreach ($sn_new as $typeid => $sn) {
-        if (isset($sn['pub']) && !is_null($sn['fullname'])) {
-            if (isset($sn_old[$typeid]) && $update_new) {
-                XDB::execute("UPDATE  profile_name
-                                 SET  particle = {?}, name = {?}, typeid = {?}
-                               WHERE  id = {?} AND pid = {?}",
-                             $sn['particle'], $sn['name'], $typeid, $sn_old[$typeid]['id'], $pid);
-                unset($sn_old[$typeid]);
-            } elseif ($sn['fullname'] == $sn_old[$typeid]['fullname'] && $sn['name'] == $sn_old[$typeid]['name']) {
-                XDB::execute('INSERT INTO  profile_name (particle, name, typeid, pid)
-                                   VALUES  ({?}, {?}, {?}, {?})',
-                             $sn_old[$typeid]['particle'], $sn_old[$typeid]['name'], $typeid, $pid);
-                unset($sn_old[$typeid]);
-            } else {
-                $has_new = true;
-            }
-        } else {
-            if ($sn['fullname'] != '') {
-                XDB::execute("INSERT INTO  profile_name (particle, name, typeid, pid)
-                                   VALUES  ('', {?}, {?}, {?})",
-                             $sn['fullname'], $typeid, $pid);
-            }
-            $i = 0;
-            while (isset($sn[$i])) {
-                XDB::execute("INSERT INTO  profile_name (particle, name, typeid, pid)
-                                   VALUES  ('', {?}, {?}, {?})",
-                             $sn[$i], $typeid, $pid);
-                $i++;
-            }
-        }
-    }
-    if (count($sn_old) > 0) {
-        if (!$update_new) {
-            $has_new = true;
-            foreach ($sn_old as $typeid => $sn) {
-                XDB::execute("INSERT INTO  profile_name (particle, name, typeid, pid)
-                                   VALUES  ({?}, {?}, {?}, {?})",
-                             $sn['particle'], $sn['name'], $typeid, $pid);
-            }
-        } else {
-            foreach ($sn_old as $typeid => $sn) {
-                XDB::execute("DELETE FROM  profile_name
-                                    WHERE  pid = {?} AND id = {?}",
-                             $pid, $sn['id']);
-            }
-        }
-    }
-    if ($update_new) {
-        XDB::execute('DELETE FROM  email_source_account
-                            WHERE  FIND_IN_SET(\'usage\', flags) AND uid = {?} AND type = \'alias\'',
-                     $user->id());
-    }
-    if ($new_alias) {
-        XDB::execute('INSERT INTO  email_source_account (email, uid, type, flags, domain)
-                           SELECT  {?}, {?}, \'alias\', \'usage\', id
-                             FROM  email_virtual_domains
-                            WHERE  name = {?}',
-                     $new_alias, $user->id(), $user->mainEmailDomain());
+    XDB::execute("UPDATE  accounts             AS a
+              INNER JOIN  account_profiles     AS ap  ON (ap.uid = a.uid AND FIND_IN_SET('owner', ap.perms))
+              INNER JOIN  profile_public_names AS ppn ON (ppn.pid = ap.pid)
+              INNER JOIN  profile_display      AS pd  ON (pd.pid = ap.pid)
+                     SET  a.lastname = IF(ppn.lastname_ordinary = '', ppn.lastname_main, ppn.lastname_ordinary),
+                          a.firstname = IF(ppn.firstname_ordinary = '', ppn.firstname_main, ppn.firstname_ordinary),
+                          a.full_name = pd.short_name, a.directory_name = pd.directory_name
+                   WHERE  a.uid = {?}",
+                 $uid);
+}
+
+function update_display_names(Profile $profile, array $public_names, array $private_names = null)
+{
+    if (is_null($private_names)) {
+        $private_names = XDB::fetchAllAssoc('SELECT  type, name
+                                               FROM  profile_private_names
+                                              WHERE  pid = {?}
+                                           ORDER BY  type, id',
+                                            $profile->id());
     }
+    $display_names = build_display_names($public_names, $private_names, $profile->isFemale());
+
+    XDB::execute('UPDATE  profile_display
+                     SET  public_name = {?}, private_name = {?},
+                          directory_name = {?}, short_name = {?}, sort_name = {?}
+                   WHERE  pid = {?}',
+                 $display_names['public_name'], $display_names['private_name'],
+                 $display_names['directory_name'], $display_names['short_name'],
+                 $display_names['sort_name'], $profile->id());
+
+    Profile::rebuildSearchTokens($profile->id(), false);
 
-    // XXX: Improve this when we optimize names handling.
-    // Updates accounts firt and last names.
-    XDB::execute('UPDATE  accounts          AS a
-              INNER JOIN  account_profiles  AS ap ON (ap.uid = a.uid AND FIND_IN_SET(\'owner\', ap.perms))
-              INNER JOIN  profile_name_enum AS le ON (le.type = \'lastname\')
-              INNER JOIN  profile_name_enum AS ce ON (ce.type = \'lastname_ordinary\')
-              INNER JOIN  profile_name      AS l  ON (ap.pid = l.pid AND le.id = l.typeid)
-               LEFT JOIN  profile_name      AS c  ON (ap.pid = c.pid AND ce.id = c.typeid)
-                     SET  a.lastname = IF(c.pid IS NULL, IF(l.particle != \'\', l.name, CONCAT(l.particle, \' \', l.name)),
-                                                         IF(c.particle != \'\', c.name, CONCAT(c.particle, \' \', c.name)))
-                   WHERE  a.uid = {?}',
-                 $user->id());
+    if ($profile->owner()) {
+        update_account_from_profile($profile->owner()->id());
+    }
+}
 
-    XDB::execute('UPDATE  accounts          AS a
-              INNER JOIN  account_profiles  AS ap ON (ap.uid = a.uid AND FIND_IN_SET(\'owner\', ap.perms))
-              INNER JOIN  profile_name_enum AS fe ON (fe.type = \'firstname\')
-              INNER JOIN  profile_name_enum AS ce ON (ce.type = \'firstname_ordinary\')
-              INNER JOIN  profile_name      AS f  ON (ap.pid = f.pid AND fe.id = f.typeid)
-               LEFT JOIN  profile_name      AS c  ON (ap.pid = c.pid AND ce.id = c.typeid)
-                     SET  a.firstname = IF(c.pid IS NULL, f.name, c.name)
-                   WHERE  a.uid = {?}',
-                 $user->id());
+function update_public_names($pid, array $public_names)
+{
+    $public_names['particles'] = new PlFlagSet();
+    static $suffixes = array('main', 'marital', 'ordinary');
+    foreach ($suffixes as $suffix) {
+        if (isset($public_names['particle_' . $suffix]) && ($public_names['particle_' . $suffix] == 1 || $public_names['particle_' . $suffix] == 'on')) {
+            $public_names['particles']->addFlag($suffix, 1);
+        }
+    }
 
-    Profile::rebuildSearchTokens($pid, false);
-    return $has_new;
+    XDB::execute('UPDATE  profile_public_names
+                     SET  particles = {?}, lastname_main = {?}, lastname_marital = {?}, lastname_ordinary = {?},
+                          firstname_main = {?}, firstname_ordinary = {?}, pseudonym = {?}
+                   WHERE  pid = {?}',
+                 $public_names['particles'], $public_names['lastname_main'], $public_names['lastname_marital'], $public_names['lastname_ordinary'],
+                 $public_names['firstname_main'], $public_names['firstname_ordinary'], $public_names['pseudonym'], $pid);
 }
 
 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
index 4d6eb66..8590eb7 100644 (file)
@@ -26,46 +26,35 @@ class NamesReq extends ProfileValidate
     // {{{ properties
 
     public $unique = true;
-
-    public $sn_old;
-    public $sn_new;
-    public $display_names;
-    public $mail_domain;
-    public $old_alias;
-    public $new_alias;
-    public $sn_types;
-
+    public $public_names;
+    public $old_public_names;
+    public $old_alias = null;
+    public $new_alias = null;
+    public $descriptions = array('lastname_main' => 'Nom patronymique', 'lastname_marital' => 'Nom marital', 'lastname_ordinary' => 'Nom usuel', 'firstname_main' => 'Prénom', 'firstname_ordinary' => 'Prénom usuel', 'pseudonym' => 'Pseudonyme (nom de plume)');
     public $rules = "Refuser tout ce qui n'est visiblement pas un nom de famille (ce qui est extremement rare car à peu près n'importe quoi peut être un nom de famille).";
 
     // }}}
     // {{{ constructor
 
-    public function __construct(User $_user, Profile $_profile, $_search_names, $_private_name_end)
+    public function __construct(User $_user, Profile $_profile, array $_public_names, array $_old_public_names)
     {
         parent::__construct($_user, $_profile, true, 'usage');
-        require_once 'name.func.inc.php';
 
-        $this->sn_types  = build_types();
-        $this->sn_old    = build_sn_pub($this->profile->id());
-        $this->sn_new    = $_search_names;
-        $this->new_alias = true;
-        $this->display_names = array();
-        $this->mail_domain = $this->profileOwner->mainEmailDomain();
-
-        build_display_names($this->display_names, $_search_names,
-                            $this->profile->isFemale(), $_private_name_end, $this->new_alias);
-        foreach ($this->sn_new AS $key => &$sn) {
-            if (!isset($sn['pub'])) {
-                unset($this->sn_new[$key]);
-            }
-        }
+        $this->public_names = $_public_names;
+        $this->old_public_names = $_old_public_names;
 
         if (!is_null($this->profileOwner)) {
+            require_once 'name.func.inc.php';
+
+            $this->new_alias = build_email_alias($this->public_names);
             $this->old_alias = XDB::fetchOneCell('SELECT  email
                                                     FROM  email_source_account
                                                    WHERE  uid = {?} AND type = \'alias\' AND FIND_IN_SET(\'usage\', flags)',
                                                  $this->profileOwner->id());
-            if ($this->old_alias != $this->new_alias) {
+
+            if ($this->old_alias == $this->new_alias) {
+                $this->old_alias = $this->new_alias = null;
+            } else {
                 $used = XDB::fetchOneCell('SELECT  COUNT(uid)
                                              FROM  email_source_account
                                             WHERE  email = {?} AND type != \'alias_aux\'',
@@ -130,11 +119,24 @@ class NamesReq extends ProfileValidate
     {
         require_once 'name.func.inc.php';
 
-        set_profile_display($this->display_names, $this->profile);
+        update_public_names($this->profile->id(), $this->public_names);
+        update_display_names($this->profile, $this->public_names);
 
         if (!is_null($this->profileOwner)) {
-            set_alias_names($this->sn_new, $this->sn_old, $this->profile->id(),
-                            $this->profileOwner, true, $this->new_alias);
+            if (!is_null($this->old_alias)) {
+                XDB::execute('DELETE FROM  email_source_account
+                                    WHERE  FIND_IN_SET(\'usage\', flags) AND uid = {?} AND type = \'alias\'',
+                             $this->profileOwner->id());
+            }
+            if (!is_null($this->new_alias)) {
+                XDB::execute('INSERT INTO  email_source_account (email, uid, type, flags, domain)
+                                   SELECT  {?}, {?}, \'alias\', \'usage\', id
+                                     FROM  email_virtual_domains
+                                    WHERE  name = {?}',
+                             $this->new_alias, $this->profileOwner->id(), $this->profileOwner->mainEmailDomain());
+            }
+            require_once 'emails.inc.php';
+            fix_bestalias($this->profileOwner);
 
             // Update the local User object, to pick up the new bestalias.
             $this->profileOwner = User::getSilentWithUID($this->profileOwner->id());
@@ -144,6 +146,18 @@ class NamesReq extends ProfileValidate
     }
 
     // }}}
+    // {{{ function getPublicNames()
+
+    static public function getPublicNames($pid)
+    {
+        if ($request = parent::get_typed_request($pid, 'usage')) {
+            return $request->public_names;
+        }
+        return false;
+    }
+
+    // }}}
+
 }
 // }}}
 
index fa56a3c..60d18fa 100644 (file)
@@ -174,10 +174,7 @@ function get_nouveau_infos($method, $params) {
     }
     // We check we actually have an identification number.
     if(!empty($params[1])) {
-        $nameTypes = DirEnum::getOptions(DirEnum::NAMETYPES);
-        $nameTypes = array_flip($nameTypes);
-
-        $res = XDB::query("SELECT  pnl.name AS nom, pnu.name AS nom_usage, pnf.name AS prenom,
+        $res = XDB::query("SELECT  ppn.lastname_initial AS nom, ppn.lastname_ordinary AS nom_usage, ppn.firstname_initial AS prenom,
                                    p.sex = 'female' AS femme, p.deathdate IS NOT NULL AS decede,
                                    p.birthdate, pd.promo, CONCAT(e.email, '@', d.name) AS mail
                              FROM  profiles         AS p
@@ -185,12 +182,9 @@ function get_nouveau_infos($method, $params) {
                        INNER JOIN  email_source_account AS s ON (s.uid = ap.uid AND FIND_IN_SET('bestalias', s.flags))
                        INNER JOIN  email_virtual_domains AS d ON (s.domain = s.id)
                        INNER JOIN  profile_display  AS pd PN (p.pid = pd.pid)
-                       INNER JOIN  profile_name AS pnl ON (p.pid = pnl.pid AND pnl.typeid = {?})
-                       INNER JOIN  profile_name AS pnf ON (p.pid = pnf.pid AND pnf.typeid = {?})
-                       INNER JOIN  profile_name AS pnu ON (p.pid = pnu.pid AND pnu.typeid = {?})
+                       INNER JOIN  profile_public_names AS ppn ON (ppn.pid = p.pid)
                             WHERE  a.flags = 'bestalias' AND p.xorg_id = {?}",
-                          $nameTypes['name_ini'], $nameTypes['lastname_ordinary'],
-                          $nameTypes['firstname_ini'], $params[1]);
+                          $params[1]);
         // $data['mail'] .= '@polytechnique.org';
 
 
index 0ce61e7..2318b3f 100644 (file)
@@ -816,8 +816,6 @@ class AdminModule extends PLModule
             $lines = explode("\n", Env::t('people'));
             $separator = Env::t('separator');
             $promotion = Env::i('promotion');
-            $nameTypes = DirEnum::getOptions(DirEnum::NAMETYPES);
-            $nameTypes = array_flip($nameTypes);
 
             if (Env::t('add_type') == 'promo') {
                 $eduSchools = DirEnum::getOptions(DirEnum::EDUSCHOOLS);
@@ -877,15 +875,9 @@ class AdminModule extends PLModule
                                                VALUES  ({?}, {?}, {?}, {?}, {?})',
                                          $infos['hrid'], $xorgId, (isset($infos[5]) ? $infos[5] : null), $birthDate, $sex);
                             $pid = XDB::insertId();
-                            XDB::execute('INSERT INTO  profile_name (pid, name, typeid)
-                                               VALUES  ({?}, {?}, {?}),
-                                                       ({?}, {?}, {?}),
-                                                       ({?}, {?}, {?}),
-                                                       ({?}, {?}, {?})',
-                                         $pid, $infos[0], $nameTypes['name_ini'],
-                                         $pid, $infos[0], $nameTypes['lastname'],
-                                         $pid, $infos[1], $nameTypes['firstname_ini'],
-                                         $pid, $infos[1], $nameTypes['firstname']);
+                            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]);
                             XDB::execute('INSERT INTO  profile_display (pid, yourself, public_name, private_name,
                                                                         directory_name, short_name, sort_name, promo)
                                                VALUES  ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})',
index 4ee5fb9..0ad1a74 100644 (file)
@@ -47,7 +47,6 @@ class ProfileModule extends PLModule
             'javascript/education.js'    => $this->make_hook('education_js',               AUTH_COOKIE),
             'javascript/grades.js'       => $this->make_hook('grades_js',                  AUTH_COOKIE),
             'profile/medal'              => $this->make_hook('medal',                      AUTH_PUBLIC),
-            'profile/name_info'          => $this->make_hook('name_info',                  AUTH_PUBLIC),
 
             'referent'                   => $this->make_hook('referent',                   AUTH_COOKIE),
             'referent/country'           => $this->make_hook('ref_country',                AUTH_COOKIE, 'user', NO_AUTH),
@@ -68,7 +67,6 @@ class ProfileModule extends PLModule
             'admin/trombino'             => $this->make_hook('admin_trombino',             AUTH_MDP,    'admin'),
             'admin/corps_enum'           => $this->make_hook('admin_corps_enum',           AUTH_MDP,    'admin'),
             'admin/corps_rank'           => $this->make_hook('admin_corps_rank',           AUTH_MDP,    'admin'),
-            'admin/names'                => $this->make_hook('admin_names',                AUTH_MDP,    'admin'),
         );
     }
 
@@ -115,19 +113,6 @@ class ProfileModule extends PLModule
         exit;
     }
 
-    function handler_name_info($page)
-    {
-        pl_content_headers("text/html");
-        $page->changeTpl('profile/name_info.tpl', SIMPLE);
-        $res = XDB::iterator("SELECT  name, explanations,
-                                      FIND_IN_SET('public', flags) AS public,
-                                      FIND_IN_SET('has_particle', flags) AS has_particle
-                                FROM  profile_name_enum
-                               WHERE  NOT FIND_IN_SET('not_displayed', flags)
-                            ORDER BY  NOT FIND_IN_SET('public', flags)");
-        $page->assign('types', $res);
-    }
-
     function handler_networking($page, $mid)
     {
         $res = XDB::query("SELECT  icon
@@ -490,14 +475,11 @@ class ProfileModule extends PLModule
     function handler_ajax_searchname($page, $id, $isFemale)
     {
         pl_content_headers("text/html");
-        $page->changeTpl('profile/general.searchname.tpl', NO_SKIN);
-        $res = XDB::query("SELECT  id, name, FIND_IN_SET('public', flags) AS pub
-                             FROM  profile_name_enum
-                            WHERE  NOT FIND_IN_SET('not_displayed', flags)
-                                   AND NOT FIND_IN_SET('always_displayed', flags)");
-        $page->assign('sn_type_list', $res->fetchAllAssoc());
+        $page->changeTpl('profile/general.private_name.tpl', NO_SKIN);
+        $page->assign('other_names', array('nickname' => 'Surnom', 'firstname' => 'Autre prénom', 'lastname' => 'Autre nom'));
+        $page->assign('new_name', true);
         $page->assign('isFemale', $isFemale);
-        $page->assign('i', $id);
+        $page->assign('id', $id);
     }
 
     function handler_ajax_buildnames($page, $data, $isFemale)
@@ -710,17 +692,6 @@ class ProfileModule extends PLModule
                 break;
         }
     }
-    function handler_admin_names($page, $action = 'list', $id = null) {
-        $page->setTitle('Administration - Types de noms');
-        $page->assign('title', 'Gestion des types de noms');
-        $table_editor = new PLTableEditor('admin/names', 'profile_name_enum', 'id', true);
-        $table_editor->describe('name', 'Nom', true);
-        $table_editor->describe('explanations', 'Explications', true);
-        $table_editor->describe('type', 'Type', true);
-        $table_editor->describe('flags', 'Flags', true);
-        $table_editor->describe('score', 'Score', true);
-        $table_editor->apply($page, $action, $id);
-    }
     function handler_admin_binets($page, $action = 'list', $id = null) {
         $page->setTitle('Administration - Binets');
         $page->assign('title', 'Gestion des binets');
index 6c29940..08b09ca 100644 (file)
 
 class ProfileSettingSearchNames implements ProfileSetting
 {
-    private $private_name_end;
-    private $search_names;
-    private $name_types;
+    private function diff($pid, array $old, array $new)
+    {
+        $diff = false;
+        foreach ($old as $field => $name) {
+            $diff = $diff || ($name != $new[$field]);
+        }
 
-    public function __construct() {
-            $this->name_types = DirEnum::getOptions(DirEnum::NAMES);
+        return $diff;
     }
 
     private function matchWord($old, $new, $newLen)
@@ -36,174 +38,84 @@ class ProfileSettingSearchNames implements ProfileSetting
             && ($i + $newLen == strlen($old) || $old{$i + $newLen} == ' ');
     }
 
-    private function prepareField($value)
+    private function prepare(ProfilePage $page, array &$new_value)
     {
-        return name_to_basename($value);
-    }
+        $initial_value = XDB::fetchOneAssoc('SELECT  lastname_main, firstname_main
+                                               FROM  profile_public_names
+                                              WHERE  pid = {?}',
+                                            $page->pid());
 
-    private function prepare(ProfilePage $page, $field, $value, $init, &$success)
-    {
         $success = true;
-        $ini     = $this->prepareField($init);
-        $new     = $this->prepareField($value);
-        $newLen  = strlen($new);
-        $success = $this->matchWord($ini, $new, $newLen)
-                   || ($field == 'lastname' && $new == 'DE ' . $ini);
-        if (!$success) {
-            $field = strtolower($field);
-            Platal::page()->trigError("Le " . $this->name_types[$field] . " que tu as choisi (" . $value .
-                                      ") est trop loin de ton " . $this->name_types[$field] . " initial (" . $init . ").");
-        }
-        return $success ? $value : $init;
-    }
+        foreach ($initial_value as $field => $name) {
+            $initial = name_to_basename($name);
+            $new = name_to_basename($new_value[$field]);
 
-    /* Removes duplicated entries for the fields that do not allow them. */
-    private function clean($value)
-    {
-        $single_types = XDB::fetchAllAssoc('id',
-                                           'SELECT  id, 0
-                                              FROM  profile_name_enum
-                                             WHERE  NOT FIND_IN_SET(\'allow_duplicates\', flags)');
-
-        foreach ($value as $key => $item) {
-            if (isset($single_types[$item['typeid']])) {
-                if ($single_types[$item['typeid']] === true) {
-                    unset($value[$key]);
-                } else {
-                    $single_types[$item['typeid']] = true;
-                }
+            if (!($this->matchWord($initial, $new, strlen($new))
+                || ($field == 'lastname_main' && $new == 'DE ' . $initial))) {
+                $new_value[$field . '_error'] = true;
+                $success = false;
+                Platal::page()->trigError('Le nom choisi (' . $new . ') est trop loin de sa valeur initiale (' . $initial . ').');
             }
         }
 
-        return $value;
+        return $success;
     }
 
     public function value(ProfilePage $page, $field, $value, &$success)
     {
-        $success     = true;
-        $success_tmp = true;
+        $success = true;
 
         if (is_null($value)) {
-            $sn_all = XDB::iterator("SELECT  CONCAT(sn.particle, sn.name) AS name,
-                                             sn.particle, sn.typeid, e.type, e.name AS type_name,
-                                             FIND_IN_SET('has_particle', e.flags) AS has_particle,
-                                             FIND_IN_SET('always_displayed', e.flags) AS always_displayed,
-                                             FIND_IN_SET('public', e.flags) AS pub
-                                       FROM  profile_name      AS sn
-                                 INNER JOIN  profile_name_enum AS e  ON (e.id = sn.typeid)
-                                      WHERE  sn.pid = {?} AND NOT FIND_IN_SET('not_displayed', e.flags)
-                                   ORDER BY  NOT FIND_IN_SET('always_displayed', e.flags), e.id, sn.name",
-                                     $page->pid());
-
-            $sn_types = XDB::iterator("SELECT  id, type, name,
-                                               FIND_IN_SET('has_particle', flags) AS has_particle
-                                         FROM  profile_name_enum
-                                        WHERE  NOT FIND_IN_SET('not_displayed', flags)
-                                               AND FIND_IN_SET('always_displayed', flags)
-                                     ORDER BY  id");
+            $request = NamesReq::getPublicNames($page->pid());
 
-            $value = array();
-            $sn = $sn_all->next();
-            while ($sn_type = $sn_types->next()) {
-                if ($sn_type['id'] == $sn['typeid']) {
-                    $value[] = $sn;
-                    if ($sn) {
-                        $sn = $sn_all->next();
-                    }
-                } else {
-                    $value[] = array('name'             => '',
-                                     'particle'         => '',
-                                     'typeid'           => $sn_type['id'],
-                                     'type'             => $sn_type['type'],
-                                     'type_name'        => $sn_type['name'],
-                                     'has_particle'     => $sn_type['has_particle'],
-                                     'always_displayed' => 1,
-                                     'pub'              => 1);
+            if (!$request) {
+                $value['public_names'] = XDB::fetchOneAssoc('SELECT  particles, lastname_main, lastname_marital, lastname_ordinary,
+                                                                     firstname_main, firstname_ordinary, pseudonym
+                                                               FROM  profile_public_names
+                                                              WHERE  pid = {?}',
+                                                            $page->pid());
+
+                $flags = new PlFlagSet($value['public_names']['particles']);
+                unset($value['public_names']['particles']);
+                static $suffixes = array('main', 'marital', 'ordinary');
+
+                foreach ($suffixes as $suffix) {
+                    $value['public_names']['particle_' . $suffix] = $flags->hasFlag($suffix);
                 }
-            }
-            if ($sn) {
-                do {
-                    $value[] = $sn;
-                } while ($sn = $sn_all->next());
-            }
-            $namesRequest = ProfileValidate::get_typed_requests($page->pid(), 'usage');
-            if (count($namesRequest) > 0) {
+            } else {
+                $value['public_names'] = $request;
                 Platal::page()->assign('validation', true);
             }
-            $value = $this->clean($value);
+
+            $value['private_names'] = XDB::fetchAllAssoc('SELECT  type, name
+                                                            FROM  profile_private_names
+                                                           WHERE  pid = {?}
+                                                        ORDER BY  type, id',
+                                                         $page->pid());
         } else {
-            require_once 'name.func.inc.php';
-
-            $value = $this->clean($value);
-            $res = XDB::query("SELECT  s.particle, s.name
-                                 FROM  profile_name      AS s
-                           INNER JOIN  profile_name_enum AS e ON (e.id = s.typeid)
-                                WHERE  s.pid = {?} AND (e.type = 'lastname' OR e.type = 'firstname')
-                             ORDER BY  e.type = 'firstname'",
-                             $page->pid());
-            $res = $res->fetchAllAssoc();
-            $initial = array();
-            $initial['lastname'] = $res[0]['particle'] . $res[0]['name'];
-            $initial['firstname'] = $res[1]['name'];
-            $sn_types = build_types();
-            $this->search_names = array();
-            foreach ($value as &$sn) {
-                $sn['name'] = trim($sn['name']);
-                if (S::user()->isMe($page->owner) && ($sn['type'] == 'firstname' || $sn['type'] == 'lastname')) {
-                    $sn['name'] = $this->prepare($page, $sn['type'], $sn['name'],
-                                                 $initial[$sn['type']], $success_tmp);
-                    $success = $success && $success_tmp;
-                }
-                if ($sn['pub']) {
-                    if (isset($sn['particle']) && ($sn['particle'] != '')) {
-                        // particle is before first blank
-                        list($particle, $name) = explode(' ', $sn['name'], 2);
-                        $particle = trim($particle) . ' ';
-                        if (!$name) {
-                            // particle is before first quote
-                            list($particle, $name) = explode('\'', $sn['name'], 2);
-                            $particle = trim($particle);
-                            if (!$name) {
-                                // actually there is no particle
-                                $particle = '';
-                                $name = $sn['name'];
-                            }
-                        }
-                    } else {
-                        $particle = '';
-                        $name     = $sn['name'];
-                    }
-                }
-                if ($sn['name'] != '') {
-                    if ($sn['pub']) {
-                        $this->search_names[$sn['typeid']] = array('fullname' => $sn['name'],
-                                                                   'name'     => $name,
-                                                                   'particle' => $particle,
-                                                                   'pub'      => $sn['pub']);
-                    } else {
-                        if (isset($this->search_names[$sn['typeid']])) {
-                            $this->search_names[$sn['typeid']][] = $sn['name'];
-                        } else {
-                            $this->search_names[$sn['typeid']] = array('fullname' => $sn['name']);
-                        }
-                        $sn['type_name'] = $sn_types[$sn['typeid']];
-                    }
+            foreach ($value['public_names'] as $key => $name) {
+                $value['public_names'][$key] = trim($name);
+            }
+            foreach ($value['private_names'] as $key => $name) {
+                $value['private_names'][$key]['name'] = trim($name['name']);
+                if ($value['private_names'][$key]['name'] == '') {
+                    unset($value['private_names'][$key]);
                 }
             }
-            $res = XDB::query("SELECT  public_name, private_name
-                                 FROM  profile_display
-                                WHERE  pid = {?}",
-                              $page->pid());
-            list($public_name, $private_name) = $res->fetchOneRow();
-            if ($success) {
-                $sn_types_private       = build_types('private');
-                $this->private_name_end = build_private_name($this->search_names, $sn_types_private);
-                $private_name           = $public_name . $this->private_name_end;
+
+            if (S::user()->isMe($page->owner)) {
+                $success = $this->prepare($page, $value['public_names']);
             }
-            Platal::page()->assign('public_name', $public_name);
-            Platal::page()->assign('private_name', $private_name);
         }
 
+        require_once 'name.func.inc.php';
+        $public_name = build_first_name($value['public_names']) . ' ' . build_full_last_name($value['public_names'], $page->profile->isFemale());
+        $private_name_end = build_private_name($value['private_names']);
+        $private_name = $public_name . $private_name_end;
+
+        Platal::page()->assign('public_name', $public_name);
+        Platal::page()->assign('private_name', $private_name);
+
         return $value;
     }
 
@@ -211,36 +123,57 @@ class ProfileSettingSearchNames implements ProfileSetting
     {
         require_once 'name.func.inc.php';
 
-        $sn_old = build_sn_pub($page->pid());
-        XDB::execute("DELETE FROM  s
-                            USING  profile_name      AS s
-                       INNER JOIN  profile_name_enum AS e ON (s.typeid = e.id)
-                            WHERE  s.pid = {?} AND NOT FIND_IN_SET('not_displayed', e.flags)",
-                     $page->pid());
-        $has_new = set_alias_names($this->search_names, $sn_old, $page->pid(), $page->owner);
+        $old = XDB::fetchOneAssoc('SELECT  lastname_main, lastname_marital, lastname_ordinary,
+                                           firstname_main, firstname_ordinary, pseudonym
+                                     FROM  profile_public_names
+                                    WHERE  pid = {?}',
+                                  $page->pid());
 
-        // Only requires validation if modification in public names
-        if ($has_new) {
-            $new_names = new NamesReq(S::user(), $page->profile, $this->search_names, $this->private_name_end);
+        if ($has_diff = $this->diff($page->pid(), $old, $value['public_names'])) {
+            $new_names = new NamesReq(S::user(), $page->profile, $value['public_names'], $old);
             $new_names->submit();
-            Platal::page()->trigWarning('La demande de modification de tes noms a bien été prise en compte.' .
-                                        ' Tu recevras un email dès que ces changements auront été effectués.');
+            Platal::page()->assign('validation', true);
+            Platal::page()->trigWarning('La demande de modification des noms a bien été prise en compte.' .
+                                        ' Un email sera envoyé dès que ces changements auront été effectués.');
+        }
+
+        XDB::execute('DELETE FROM  profile_private_names
+                            WHERE  pid = {?}',
+                     $page->pid());
+        $values = array();
+        $nickname = $lastname = $firstname = 0;
+        foreach ($value['private_names'] as $name) {
+            $values[] = XDB::format('({?}, {?}, {?}, {?})', $page->pid(), $name['type'], $$name['type']++, $name['name']);
+        }
+        if (count($values)) {
+            XDB::rawExecute('INSERT INTO  profile_private_names (pid, type, id, name)
+                                  VALUES  ' . implode(',', $values));
+        }
+
+        if ($has_diff) {
+            update_display_names($page->profile, $old, $value['private_names']);
         } else {
-            $display_names = array();
-            build_display_names($display_names, $this->search_names,
-                                $page->profile->isFemale(), $this->private_name_end);
-            set_profile_display($display_names, $page->profile);
+            update_display_names($page->profile, $value['public_names'], $value['private_names']);
         }
     }
 
     public function getText($value) {
-        $names = array();
-        foreach ($value as $name) {
-            if ($name['name'] != '') {
-                $names[] = mb_strtolower($name['type_name']) . ' : ' . $name['name'];
+        $public_names = array();
+        foreach ($value['public_names'] as $name) {
+            if ($name != '') {
+                $public_names[] = $name;
             }
         }
-        return implode(', ' , $names);
+
+        if (count($value['private_names'])) {
+            $private_names = array();
+            foreach ($value['private_names'] as $name) {
+                $private_names[] = $name['name'];
+            }
+            return 'noms publics : ' . implode(', ' , $public_names) . ', noms privés : ' . implode(', ' , $private_names);;
+        }
+
+        return 'noms publics : ' . implode(', ' , $public_names);
     }
 }
 
@@ -795,13 +728,9 @@ class ProfilePageGeneral extends ProfilePage
                          ORDER BY  name");
         $page->assign('network_list', $res->fetchAllAssoc());
 
-        $res = XDB::query("SELECT  public_name, private_name
-                             FROM  profile_display
-                            WHERE  pid = {?}",
-                          $this->pid());
-        $res = $res->fetchOneRow();
-        $page->assign('public_name', $res[0]);
-        $page->assign('private_name', $res[1]);
+        $page->assign('lastnames', array('main' => 'Nom patronymique', 'marital' => 'Nom marital', 'ordinary' => 'Nom usuel'));
+        $page->assign('firstnames', array('firstname_main' => 'Prénom', 'firstname_ordinary' => 'Prénom usuel', 'pseudonym' => 'Pseudonyme (nom de plume)'));
+        $page->assign('other_names', array('nickname' => 'Surnom', 'firstname' => 'Autre prénom', 'lastname' => 'Autre nom'));
         $page->assign('isFemale', $this->profile->isFemale() ? 1 : 0);
     }
 }
index 3a4279a..16d02a7 100644 (file)
@@ -49,9 +49,7 @@ class RegisterModule extends PLModule
         }
 
         if ($hash) {
-            $nameTypes = DirEnum::getOptions(DirEnum::NAMETYPES);
-            $nameTypes = array_flip($nameTypes);
-            $res = XDB::query("SELECT  a.uid, a.hruid, pnl.name AS lastname, pnf.name AS firstname, p.xorg_id AS xorgid,
+            $res = XDB::query("SELECT  a.uid, a.hruid, ppn.lastname_initial AS lastname, ppn.firstname_initial AS firstname, p.xorg_id AS xorgid,
                                        pd.promo, pe.promo_year AS yearpromo, pde.degree AS edu_type,
                                        p.birthdate_ref AS birthdateRef, FIND_IN_SET('watch', a.flags) AS watch, m.hash, a.type
                                  FROM  register_marketing AS m
@@ -61,10 +59,9 @@ class RegisterModule extends PLModule
                            INNER JOIN  profile_display    AS pd  ON (p.pid = pd.pid)
                            INNER JOIN  profile_education  AS pe  ON (pe.pid = p.pid AND FIND_IN_SET('primary', pe.flags))
                            INNER JOIN  profile_education_degree_enum AS pde ON (pde.id = pe.degreeid)
-                           INNER JOIN  profile_name       AS pnl ON (p.pid = pnl.pid AND pnl.typeid = {?})
-                           INNER JOIN  profile_name       AS pnf ON (p.pid = pnf.pid AND pnf.typeid = {?})
+                           INNER JOIN  profile_public_names AS ppn ON (ppn.pid = p.pid)
                                 WHERE  m.hash = {?} AND a.state = 'pending'",
-                              $nameTypes['name_ini'], $nameTypes['firstname_ini'], $hash);
+                              $hash);
 
             if ($res->numRows() == 1) {
                 $subState->merge($res->fetchOneRow());
@@ -281,25 +278,21 @@ class RegisterModule extends PLModule
             return PL_FORBIDDEN;
         }
 
-        $nameTypes = DirEnum::getOptions(DirEnum::NAMETYPES);
-        $nameTypes = array_flip($nameTypes);
-
         // Retrieve the pre-registration information using the url-provided
         // authentication token.
         $res = XDB::query("SELECT  r.uid, p.pid, r.forlife, r.bestalias, r.mailorg2,
                                    r.password, r.email, r.services, r.naissance,
-                                   pnl.name AS lastname, pnf.name AS firstname, pe.promo_year,
+                                   ppn.lastname_initial, ppn.firstname_initial, pe.promo_year,
                                    pd.promo, p.sex, p.birthdate_ref, a.type
                              FROM  register_pending AS r
                        INNER JOIN  accounts         AS a   ON (r.uid = a.uid)
                        INNER JOIN  account_profiles AS ap  ON (a.uid = ap.uid AND FIND_IN_SET('owner', ap.perms))
                        INNER JOIN  profiles         AS p   ON (p.pid = ap.pid)
-                       INNER JOIN  profile_name     AS pnl ON (p.pid = pnl.pid AND pnl.typeid = {?})
-                       INNER JOIN  profile_name     AS pnf ON (p.pid = pnf.pid AND pnf.typeid = {?})
+                       INNER JOIN  profile_public_names AS ppn ON (ppn.pid = p.pid)
                        INNER JOIN  profile_display  AS pd  ON (p.pid = pd.pid)
                        INNER JOIN  profile_education AS pe ON (pe.pid = p.pid AND FIND_IN_SET('primary', pe.flags))
                             WHERE  hash = {?} AND hash != 'INSCRIT' AND a.state = 'pending'",
-                          $nameTypes['name_ini'], $nameTypes['firstname_ini'], $hash);
+                          $hash);
         if (!$hash || $res->numRows() == 0) {
             $page->kill("<p>Cette adresse n'existe pas, ou plus, sur le serveur.</p>
                          <p>Causes probables&nbsp;:</p>
index fbb6ad3..42d066d 100644 (file)
       &nbsp;&nbsp;|&nbsp;&nbsp;
       <a href="admin/sections">Sections</a>
       &nbsp;&nbsp;|&nbsp;&nbsp;
-      <a href="admin/names">Noms</a>
-      &nbsp;&nbsp;|&nbsp;&nbsp;
       <a href="admin/networking">Networking</a>
       &nbsp;&nbsp;|&nbsp;&nbsp;
       <a href="admin/profile">Modifications récentes</a>
index 57383a7..2e33212 100644 (file)
   <td class="titre">Nouvel alias&nbsp;:</td>
   <td>{$valid->new_alias}</td>
 </tr>
-{foreach from=$valid->sn_new item=sn key=typeid}
+{foreach from=$valid->public_names item=name key=type}
 <tr class="impair">
-  <td class="titre">*{$valid->sn_types.$typeid}&nbsp;:</td>
-  <td>{$sn.name}</td>
+  <td class="titre">*{$valid->descriptions.$type}&nbsp;:</td>
+  <td>{$name}</td>
 </tr>
 {/foreach}
-{foreach from=$valid->sn_old item=sn key=typeid}
+{foreach from=$valid->old_public_names item=name key=type}
 <tr class="impair">
-  <td class="titre">&#8224;{$valid->sn_types.$typeid}&nbsp;:</td>
-  <td>{$sn.name}</td>
+  <td class="titre">&#8224;{$valid->descriptions.$type}&nbsp;:</td>
+  <td>{$name}</td>
 </tr>
 {/foreach}
 <tr class="impair">
diff --git a/templates/profile/general.private_name.tpl b/templates/profile/general.private_name.tpl
new file mode 100644 (file)
index 0000000..15dbeda
--- /dev/null
@@ -0,0 +1,44 @@
+{**************************************************************************}
+{*                                                                        *}
+{*  Copyright (C) 2003-2011 Polytechnique.org                             *}
+{*  http://opensource.polytechnique.org/                                  *}
+{*                                                                        *}
+{*  This program is free software; you can redistribute it and/or modify  *}
+{*  it under the terms of the GNU General Public License as published by  *}
+{*  the Free Software Foundation; either version 2 of the License, or     *}
+{*  (at your option) any later version.                                   *}
+{*                                                                        *}
+{*  This program is distributed in the hope that it will be useful,       *}
+{*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *}
+{*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *}
+{*  GNU General Public License for more details.                          *}
+{*                                                                        *}
+{*  You should have received a copy of the GNU General Public License     *}
+{*  along with this program; if not, write to the Free Software           *}
+{*  Foundation, Inc.,                                                     *}
+{*  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA               *}
+{*                                                                        *}
+{**************************************************************************}
+
+{assign var=type value=$name.type}
+<tr class="names_advanced" id="search_name_{$id}" {if !$errors.search_names && !t($new_name)}style="display: none"{/if}>
+  <td>
+    <span class="flags">{icon name="flag_red" title="site privé"}</span>{if !t($new_name)}&nbsp;{$other_names.$type}{else}
+    <select name="search_names[private_names][{$id}][type]">
+    {foreach from=$other_names item=description key=type}
+      <option value="{$type}">{$description}</option>
+    {/foreach}
+    </select>
+    {/if}
+  </td>
+  <td>
+    {if !t($new_name)}<input type="hidden" name="search_names[private_names][{$id}][type]" value="{$type}" />{/if}
+    <input type="text" name="search_names[private_names][{$id}][name]" value="{$name.name}"
+      size="25" onkeyup="updateNameDisplay({$isFemale});"/>
+  </td>
+  <td>
+    <a href="javascript:removeSearchName({$id}, {$isFemale})">{icon name=cross title="Supprimer ce nom"}</a>
+  </td>
+</tr>
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
diff --git a/templates/profile/general.public_names.tpl b/templates/profile/general.public_names.tpl
new file mode 100644 (file)
index 0000000..adbdb12
--- /dev/null
@@ -0,0 +1,57 @@
+{**************************************************************************}
+{*                                                                        *}
+{*  Copyright (C) 2003-2011 Polytechnique.org                             *}
+{*  http://opensource.polytechnique.org/                                  *}
+{*                                                                        *}
+{*  This program is free software; you can redistribute it and/or modify  *}
+{*  it under the terms of the GNU General Public License as published by  *}
+{*  the Free Software Foundation; either version 2 of the License, or     *}
+{*  (at your option) any later version.                                   *}
+{*                                                                        *}
+{*  This program is distributed in the hope that it will be useful,       *}
+{*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *}
+{*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *}
+{*  GNU General Public License for more details.                          *}
+{*                                                                        *}
+{*  You should have received a copy of the GNU General Public License     *}
+{*  along with this program; if not, write to the Free Software           *}
+{*  Foundation, Inc.,                                                     *}
+{*  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA               *}
+{*                                                                        *}
+{**************************************************************************}
+
+{foreach from=$lastnames key=suffix item=description}
+{assign var=type value="lastname_"|cat:$suffix}
+{assign var=error value=$type|cat:"_error"}
+{assign var=particle value="particle_"|cat:$suffix}
+<tr class="names_advanced" {if !$errors.search_names}style="display: none"{/if}>
+  <td>
+    <span class="flags">{icon name="flag_green" title="site public"}</span>&nbsp;{$description}
+  </td>
+  <td>
+    <input type="text" name="search_names[public_names][{$type}]" value="{$names.$type}"
+      title="Coche la case en bout de ligne si ton nom commence par une particule."
+      {if t($names.$error)} class="error"{/if} size="25" onkeyup="updateNameDisplay({$isFemale});"/>
+  </td>
+  <td>
+    <input type="checkbox"{if t($names.$particle) neq ''} checked="checked"{/if}
+      title="Coche cette case si ton nom commence par une particule." />
+  </td>
+</tr>
+{/foreach}
+
+{foreach from=$firstnames key=type item=description}
+{assign var=error value=$type|cat:"_error"}
+<tr class="names_advanced" {if !$errors.search_names}style="display: none"{/if}>
+  <td>
+    <span class="flags">{icon name="flag_green" title="site public"}</span>&nbsp;{$description}
+  </td>
+  <td>
+    <input type="text" name="search_names[public_names][{$type}]" value="{$names.$type}"
+      {if t($names.$error)} class="error"{/if} size="25" onkeyup="updateNameDisplay({$isFemale});" />
+  </td>
+  <td></td>
+</tr>
+{/foreach}
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
diff --git a/templates/profile/general.searchname.tpl b/templates/profile/general.searchname.tpl
deleted file mode 100644 (file)
index 8ede1d9..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-{**************************************************************************}
-{*                                                                        *}
-{*  Copyright (C) 2003-2011 Polytechnique.org                             *}
-{*  http://opensource.polytechnique.org/                                  *}
-{*                                                                        *}
-{*  This program is free software; you can redistribute it and/or modify  *}
-{*  it under the terms of the GNU General Public License as published by  *}
-{*  the Free Software Foundation; either version 2 of the License, or     *}
-{*  (at your option) any later version.                                   *}
-{*                                                                        *}
-{*  This program is distributed in the hope that it will be useful,       *}
-{*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *}
-{*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *}
-{*  GNU General Public License for more details.                          *}
-{*                                                                        *}
-{*  You should have received a copy of the GNU General Public License     *}
-{*  along with this program; if not, write to the Free Software           *}
-{*  Foundation, Inc.,                                                     *}
-{*  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA               *}
-{*                                                                        *}
-{**************************************************************************}
-
-<tr id="search_name_{$i}"{if t($class)} class="{$class}" {if !t($error_name)}style="{$style}"{/if}{/if}>
-  <td>
-    <input type="hidden" name="search_names[{$i}][always_displayed]" value="{$sn.always_displayed}"/>
-    <input type="hidden" name="search_names[{$i}][has_particle]" value="{$sn.has_particle}"/>
-    <span class="flags">
-      <span id="flag_{$i}">{if $sn.pub}{icon name="flag_green" title="site public"}
-      {else}{icon name="flag_red" title="site privé"}{/if}</span>
-    </span>&nbsp;
-    {if t($sn_type_list)}
-    <select id="search_name_select_{$i}" name="search_names[{$i}][typeid]"
-      onchange="changeNameFlag({$i});updateNameDisplay({$isFemale});">
-        {foreach from=$sn_type_list item=sn_type}
-          <option value="{$sn_type.id}">{$sn_type.name}</option>
-        {/foreach}
-    </select>
-    {foreach from=$sn_type_list item=sn_type}
-    <input type="hidden" name="sn_type_{$sn_type.id}_{$i}" value="{$sn_type.pub}"/>
-    {/foreach}
-    {else}
-    {$sn.type_name}
-    <input type="hidden" name="search_names[{$i}][pub]" value="{$sn.pub}"/>
-    <input type="hidden" name="search_names[{$i}][type]" value="{$sn.type}"/>
-    <input type="hidden" name="search_names[{$i}][type_name]" value="{$sn.type_name}"/>
-    <input type="hidden" name="search_names[{$i}][typeid]" value="{$sn.typeid}"/>
-    {/if}
-  </td>
-  <td>
-    <input type="text" name="search_names[{$i}][name]" value="{$sn.name}"
-      {if $sn.has_particle}title="Coche la case en bout de ligne si ton nom commence par une particule."{/if}
-      {if t($sn.error)} class="error"{/if} size="25" onkeyup="updateNameDisplay({$isFemale});"/>
-  </td>
-  <td>
-    {if $sn.has_particle}<input type="checkbox"{if $sn.particle neq ''} checked="checked"{/if}
-      title="Coche cette case si ton nom commence par une particule." onchange="toggleParticle({$i});"/>
-    {/if}
-    <input type="hidden"  name="search_names[{$i}][particle]" value="{$sn.particle}"/>
-    {if !$sn.always_displayed}<a href="javascript:removeSearchName({$i},{$isFemale})">
-      {icon name=cross title="Supprimer ce nom"}
-    </a>{/if}
-  </td>
-</tr>
-
-{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
index e23aec5..f0ddda7 100644 (file)
       <span class="titre">Gestion des noms, prénoms, surnoms...</span>
       <span class="smaller">Ils déterminent la façon dont
       {if $isMe}ton{else}son{/if} nom apparaît sur les annuaires
-      en ligne et papier et ta fiche apparaitra quand on cherche un de ces noms. Pour plus
-      d'explications sur l'icône suivante
-      <a href="profile/name_info" class="popup3">{icon name="information" title="Plus d'infos"}</a>.</span><br/>
+      en ligne et papier et ta fiche apparaitra quand on cherche un de ces noms.</span><br/>
       <div class="small center">Si un de tes noms commence par une particule,
       coche la case en bout de ligne.</div>
     </td>
   </tr>
-  {foreach from=$search_names item=sn key=id}
-    {include file="profile/general.searchname.tpl" i=$id sn=$sn
-    class="names_advanced" style="display: none" error_name=$errors.search_names}
+  {include file="profile/general.public_names.tpl" names=$search_names.public_names}
+  {foreach from=$search_names.private_names key=id item=name}
+    {include file="profile/general.private_name.tpl"}
   {/foreach}
   <tr class="names_advanced" id="searchname" {if !$errors.search_names}style="display: none"{/if}>
     <td colspan="3">
diff --git a/upgrade/1.1.2/03_names.sql b/upgrade/1.1.2/03_names.sql
new file mode 100644 (file)
index 0000000..9c04c51
--- /dev/null
@@ -0,0 +1,106 @@
+DROP TABLE IF EXISTS profile_public_names;
+CREATE TABLE IF NOT EXISTS profile_public_names (
+  pid INT(11) UNSIGNED NOT NULL DEFAULT 0,
+  particles SET('initial', 'main', 'marital', 'ordinary') NOT NULL DEFAULT '',
+  lastname_initial VARCHAR(255) NOT NULL DEFAULT '',
+  lastname_main VARCHAR(255) NOT NULL DEFAULT '',
+  lastname_marital VARCHAR(255) NOT NULL DEFAULT '',
+  lastname_ordinary VARCHAR(255) NOT NULL DEFAULT '',
+  firstname_initial VARCHAR(255) NOT NULL DEFAULT '',
+  firstname_main VARCHAR(255) NOT NULL DEFAULT '',
+  firstname_ordinary VARCHAR(255) NOT NULL DEFAULT '',
+  pseudonym VARCHAR(255) NOT NULL DEFAULT '',
+  PRIMARY KEY (pid),
+  FOREIGN KEY (pid) REFERENCES profiles (pid) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+DROP TABLE IF EXISTS profile_private_names;
+CREATE TABLE IF NOT EXISTS profile_private_names (
+  pid INT(11) UNSIGNED NOT NULL DEFAULT 0,
+  type ENUM('lastname', 'firstname', 'nickname') NOT NULL DEFAULT 'nickname',
+  id TINYINT(2) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'id of the name among those sharing the same pid / general_type',
+  name VARCHAR(255) NOT NULL DEFAULT '',
+  PRIMARY KEY (pid, type, id),
+  FOREIGN KEY (pid) REFERENCES profiles (pid) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- Initiates profile_public_names.
+INSERT INTO  profile_public_names (pid)
+     SELECT  pid
+       FROM  profiles;
+
+-- Insert lastnames.
+    UPDATE  profile_public_names AS ppn
+INNER JOIN  profile_name         AS pn  ON (pn.pid = ppn.pid)
+INNER JOIN  profile_name_enum    AS pne ON (pn.typeid = pne.id)
+       SET  ppn.lastname_initial = IF(pn.particle = '', pn.name, CONCAT(pn.particle, ' ', pn.name)),
+            ppn.particles = IF(pn.particle = '', '', 'initial')
+     WHERE  pne.type = 'name_ini';
+    UPDATE  profile_public_names AS ppn
+INNER JOIN  profile_name         AS pn  ON (pn.pid = ppn.pid)
+INNER JOIN  profile_name_enum    AS pne ON (pn.typeid = pne.id)
+       SET  ppn.lastname_main = IF(pn.particle = '', pn.name, CONCAT(pn.particle, ' ', pn.name)),
+            ppn.particles = IF(pn.particle = '', ppn.particles, CONCAT_WS(',', ppn.particles, 'main'))
+     WHERE  pne.type = 'lastname';
+UPDATE  profile_public_names
+   SET  particles = TRIM(BOTH ',' FROM particles);
+    UPDATE  profile_public_names AS ppn
+INNER JOIN  profile_name         AS pn  ON (pn.pid = ppn.pid)
+INNER JOIN  profile_name_enum    AS pne ON (pn.typeid = pne.id)
+       SET  ppn.lastname_marital = IF(pn.particle = '', pn.name, CONCAT(pn.particle, ' ', pn.name)),
+            ppn.particles = IF(pn.particle = '', ppn.particles, CONCAT_WS(',', ppn.particles, 'marital'))
+     WHERE  pne.type = 'lastname_marital';
+UPDATE  profile_public_names
+   SET  particles = TRIM(BOTH ',' FROM particles);
+    UPDATE  profile_public_names AS ppn
+INNER JOIN  profile_name         AS pn  ON (pn.pid = ppn.pid)
+INNER JOIN  profile_name_enum    AS pne ON (pn.typeid = pne.id)
+       SET  ppn.lastname_ordinary = IF(pn.particle = '', pn.name, CONCAT(pn.particle, ' ', pn.name)),
+            ppn.particles = IF(pn.particle = '', ppn.particles, CONCAT_WS(',', ppn.particles, 'ordinary'))
+     WHERE  pne.type = 'lastname_ordinary';
+UPDATE  profile_public_names
+   SET  particles = TRIM(BOTH ',' FROM particles);
+
+-- Insert other names.
+    UPDATE  profile_public_names AS ppn
+INNER JOIN  profile_name         AS pn  ON (pn.pid = ppn.pid)
+INNER JOIN  profile_name_enum    AS pne ON (pn.typeid = pne.id)
+       SET  ppn.firstname_initial = pn.name
+     WHERE  pne.type = 'firstname_ini';
+    UPDATE  profile_public_names AS ppn
+INNER JOIN  profile_name         AS pn  ON (pn.pid = ppn.pid)
+INNER JOIN  profile_name_enum    AS pne ON (pn.typeid = pne.id)
+       SET  ppn.firstname_main = pn.name
+     WHERE  pne.type = 'firstname';
+    UPDATE  profile_public_names AS ppn
+INNER JOIN  profile_name         AS pn  ON (pn.pid = ppn.pid)
+INNER JOIN  profile_name_enum    AS pne ON (pn.typeid = pne.id)
+       SET  ppn.firstname_ordinary = pn.name
+     WHERE  pne.type = 'firstname_other';
+    UPDATE  profile_public_names AS ppn
+INNER JOIN  profile_name         AS pn  ON (pn.pid = ppn.pid)
+INNER JOIN  profile_name_enum    AS pne ON (pn.typeid = pne.id)
+       SET  ppn.pseudonym = pn.name
+     WHERE  pne.type = 'pseudonym';
+
+-- Insert privates names.
+INSERT INTO  profile_private_names (pid, type, id, name)
+     SELECT  pn.pid, 'nickname', 0, pn.name
+       FROM  profile_name      AS pn
+ INNER JOIN  profile_name_enum AS pne ON (pn.typeid = pne.id)
+      WHERE  pne.type = 'nickname';
+INSERT INTO  profile_private_names (pid, type, id, name)
+     SELECT  pn.pid, 'lastname', 0, pn.name
+       FROM  profile_name      AS pn
+ INNER JOIN  profile_name_enum AS pne ON (pn.typeid = pne.id)
+      WHERE  pne.type = 'name_other';
+INSERT INTO  profile_private_names (pid, type, id, name)
+     SELECT  pn.pid, 'firstname', 0, pn.name
+       FROM  profile_name      AS pn
+ INNER JOIN  profile_name_enum AS pne ON (pn.typeid = pne.id)
+      WHERE  pne.type = 'firstname_other';
+
+-- DROP TABLE IF EXISTS profile_name;
+-- DROP TABLE IF EXISTS profile_name_enum;
+
+-- vim:set syntax=mysql:
diff --git a/upgrade/1.1.2/README b/upgrade/1.1.2/README
new file mode 100644 (file)
index 0000000..818e00d
--- /dev/null
@@ -0,0 +1,4 @@
+Check that the following queries return the same results before updating:
+SELECT COUNT(*), COUNT(DISTINCT(pid)) FROM profile_name AS pn INNER JOIN profile_name_enum AS pne ON (pn.typeid = pne.id) WHERE pne.type = 'nickname';
+SELECT COUNT(*), COUNT(DISTINCT(pid)) FROM profile_name AS pn INNER JOIN profile_name_enum AS pne ON (pn.typeid = pne.id) WHERE pne.type = 'name_other';
+SELECT COUNT(*), COUNT(DISTINCT(pid)) FROM profile_name AS pn INNER JOIN profile_name_enum AS pne ON (pn.typeid = pne.id) WHERE pne.type = 'firstname_other';