================================================================================
+VERSION 1.1.5 XX XX XXXX
+
+Bug/Wish:
+
+ * Search:
+ - #1572: Removes remaining results count from queries -JAC
+ - #1574: Correctly displays State corps -GLN
+
+ * Validations:
+ - #1571: Fixes the opening of the comments panel -GLN
+
+ * XnetEvent:
+ - #1577: Fixes alternative payements given by admins -GLN
+ - #1578: Fixes deletion of people inscriptions -GLN
+ - #1348: Keeps the amount paid when updating participation -GLN
+
+From 1.1.4 branch:
+
+ * XnetEvent:
+ - #1566: Corrects the total number in events -GLN
+ - #1567: Payment takes into account the amount when it is given -GLN
+
+================================================================================
VERSION 1.1.4 14 11 2011
New:
--- /dev/null
+#!/usr/bin/php5 -q
+<?php
+/***************************************************************************
+ * 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 *
+ ***************************************************************************/
+
+require './connect.db.inc.php';
+require '../include/name.func.inc.php';
+
+$globals->debug = 0; // Do not store backtraces
+
+$opts = getopt('f:p:');
+
+if (empty($opts['f']) || empty($opts['p'])) {
+ print "File name missing (-f=file_name) or promotion missing (-p=file_name).\n";
+ exit;
+}
+
+$file = $opts['f'];
+$handle = fopen($file, 'r');
+$promo_year = $opts['p'];
+
+$already = array();
+$new = array();
+$ambiguous = array();
+
+while ($line = trim(fgets($handle))) {
+ $data = explode(';', $line);
+ $cond = new PFC_And(new UFC_NameTokens(split_name_for_search($data[0]), array(), false, false, Profile::LASTNAME));
+ $cond->addChild(new UFC_NameTokens(split_name_for_search($data[1]), array(), false, false, Profile::FIRSTNAME));
+ $uf = new UserFilter($cond);
+ $profiles = $uf->getProfiles();
+ switch (count($profiles)) {
+ case 0:
+ $new[] = $line;
+ break;
+ case 1:
+ foreach ($profiles as $profile) {
+ $already[] = $profile->hrid();
+ }
+ break;
+ default:
+ $hrids = array();
+ foreach ($profiles as $profile) {
+ $hrids[] = $profile->hrid();
+ }
+ $ambiguous[] = $line . ': ' . implode(', ', $hrids);
+ break;
+ }
+}
+
+$cond = new UFC_Promo('=', UserFilter::GRADE_MST, $promo_year);
+$uf = new UserFilter($cond);
+$profiles = $uf->getProfiles();
+$promo = array();
+foreach ($profiles as $profile) {
+ $promo[] = $profile->hrid();
+}
+
+$intersect = array_intersect($promo, $already);
+if (count($intersect) != count($already)) {
+ print "There seems to be a problem: intersection of this promo and already found users differ.\n";
+}
+$to_remove = array_diff($promo, $intersect);
+
+sort($new);
+sort($ambiguous);
+sort($to_remove);
+
+print "New users:\n" . implode("\n", $new) . "\n\n";
+print "Ambiguous users:\n" . implode("\n", $ambiguous) . "\n\n";
+print "Users to remove (louk out for ambiguous users before!):\n" . implode("\n", $to_remove) . "\n";
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
*/
public static function getAccountEquivalentName($name)
{
- switch ($name)
- {
- case self::DN_DIRECTORY:
- case self::DN_SORT:
+ switch ($name) {
+ case self::DN_DIRECTORY:
return 'directory_name';
- case self::DN_FULL:
- case self::DN_PUBLIC:
+ case self::DN_SORT:
+ return 'sort_name';
+ case self::DN_FULL:
+ case self::DN_PUBLIC:
+ case self::DN_PRIVATE:
+ case self::DN_SHORT:
return 'full_name';
- case self::DN_PRIVATE:
- case self::DN_SHORT:
- case self::DN_YOURSELF:
- default:
+ case self::DN_YOURSELF:
+ return 'display_name';
+ default:
return 'display_name';
}
}
'events',
'forums',
'fusionax',
+ 'fxletter',
'gadgets',
'geoloc',
'googleapps',
from="Amicale des Anciens de l'X" <reponses@amicale.polytechnique.org>
replyto=reponses@amicale.polytechnique.org
+[mails_fx]
+from="Fondation de l'Ecole polytechnique" <reponses@fondationx.fr>
+replyto=reponses@fondationx.fr
+
[marketing]
from="Marketing Polytechnique.org" <register@polytechnique.org>
-Subproject commit 7a6b4d999856fd697015f719dda5909127f899a1
+Subproject commit 6317421644b2c574711b3b12f221e04206f53d3a
--- /dev/null
+/***************************************************************************
+ * 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 *
+ ***************************************************************************/
+
+
+div.fx_mail {
+ margin : auto;
+ width : 72ex;
+ font-family : "Georgia", "Times New Roman", serif;
+ font-size : 10pt;
+ text-align : justify;
+ background-color : #fff;
+ color : #000;
+}
+
+/* Links */
+div.fx_mail a[href] {
+ background-color: transparent;
+ color : #444;
+ text-decoration : none;
+ background-image: none;
+}
+
+div.fx_mail a[href]:hover {
+ background-color: transparent;
+ color : #D44;
+ text-decoration : none;
+ background-image: none;
+}
+
+/* Title */
+div.fx_mail .title {
+ background-color: #FA2;
+ margin : 0 0 3ex;
+ padding : 4.5ex 1ex 1ex 15ex;
+ font-size : 130%;
+ font-weight : bold;
+ text-align : left;
+}
+
+/* Intro */
+div.fx_mail div.intro {
+ margin : 4ex 2ex 2ex 2ex;
+}
+
+div.fx_mail div.signature {
+ margin : 3ex 2ex 0 0;
+ font-size : 90%;
+ font-style: italic;
+ text-align : right;
+}
+
+/* Give */
+div.fx_mail div.give {
+ font-weight: bold;
+ text-align: center;
+ padding: 0.5ex 0 0.5ex 0;
+ border-top: solid 2ex #FA2;
+}
+
+/* Footer */
+div.fx_mail div.foot1, div.fx_mail div.foot2 {
+ background-color: #FA2;
+ text-align: center;
+ font-size: 90%;
+ padding: 0.5ex 0;
+}
// }}}
// {{{ Regexps to wipe out from search queries
-var default_form_values = [ /&woman=0(&|$)/, /&subscriber=0(&|$)/, /&alive=0(&|$)/, /&egal[12]=[^&]*&promo[12]=(&|$)/g, /&networking_type=0(&|$)/, /&[^&=]+=(&|$)/g ];
+var default_form_values = [ /&woman=0(&|$)/, /&subscriber=0(&|$)/, /&alive=0(&|$)/, /&egal2=[^&]*&promo2=(&|$)/,
+ /&egal1=[^&]*&promo1=&edu_type=(?:Ing[^n]+nieur|Master|Doctorat)(&|$)/, /&networking_type=0(&|$)/,
+ /&origin_corps=0(&|$)/, /¤t_corps=0(&|$)/,
+ /corps_rank=0(&|$)/, /&has_email_redirect=0(&|$)/, /&[^&=]+=(&|$)/g ];
/** Uses javascript to clean form from all empty fields */
function cleanForm(f, targeturl)
} while (old_query != query);
}
}
- query = query.replace(/^&*(.*)&*$/, '$1');
+ query = query.replace(/^(.*)&+$/, '$1');
+ query = query.replace(/^&+(.*)$/, '$1');
+
+ // Removes "(n camarades)" if any of them are remaining.
+ query = query.replace(/\+\(\d+\+camarade(?:s)?\)/, '');
if (query == 'rechercher=Chercher') {
alert("Aucun critère n'a été spécifié.");
return false;
--- /dev/null
+/***************************************************************************
+ * 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 *
+ ***************************************************************************/
+
+function xStateChange(box, baseurl)
+{
+ $('.details').toggle();
+ $('#search_result').updateHtml(baseurl + 'member/new/ajax?login=' + $('#email').val());
+}
+
+var nom;
+var prenom;
+var promo;
+function searchX(baseurl)
+{
+ if ($('#nom').val() == nom && $('#prenom').val() == prenom && $('#promo').val() == promo) {
+ return;
+ }
+ nom = $('#nom').val();
+ prenom = $('#prenom').val();
+ promo = $('#promo').val();
+ $('#search_result').updateHtml(baseurl + 'member/new/ajax?prenom=' + prenom + '&nom=' + nom + '&promo=' + promo,
+ function (data) {
+ updateSuggestions(baseurl, $('select:[name=userid]').val());
+ });
+}
+
+function updateSuggestions(baseurl, uid)
+{
+ $('#broken').hide();
+ $('#marketing').hide();
+ if (uid && uid != 0) {
+ $.xget(baseurl + 'member/reg/' + uid, function(data) {
+ if (data) {
+ $('#broken').show();
+ $('#broken').find('[name=broken]').attr('checked', 'checked');
+ } else {
+ $('#marketing').show();
+ $('#marketing').find('[name=marketing]').attr('checked', 'checked');
+ }
+ });
+ }
+}
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
***************************************************************************/
+class Particles
+{
+ // 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.
+ public 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();
$firstname = build_first_name($public_names);
$display_names = array();
- $display_names['public_name'] = $firstname . ' ' . $full_last_name;
+ $display_names['public_name'] = build_full_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;
+ $display_names['directory_name'] = build_directory_name($firstname, $full_last_name);
+ $display_names['short_name'] = build_full_name($firstname, $short_last_name);
+ $display_names['sort_name'] = build_sort_name($firstname, $short_last_name);
return $display_names;
}
return ' (' . implode(', ', $names_array) . ')';
}
+function build_directory_name($firstname, $lastname)
+{
+ if ($firstname == '') {
+ return mb_strtoupper($lastname);
+ }
+ return mb_strtoupper($lastname) . ' ' . $firstname;
+}
+
+function build_full_name($firstname, $lastname)
+{
+ if ($firstname == '') {
+ return $lastname;
+ }
+ return $firstname . ' ' . $lastname;
+}
+
+// Returns the name on which the sort is performed, according to French
+// typographic rules.
+function build_sort_name($firstname, $lastname)
+{
+ // Remove uncapitalized particles.
+ $particles = "/^(d'|(" . implode(Particles::$particles, '|') . ') )/';
+ $name = preg_replace($particles, '', $lastname);
+ // Mac must also be uniformized.
+ $lastname = preg_replace("/^(Mac|Mc)( |)/", 'Mac', $name);
+
+ if ($firstname == '') {
+ return $lastname;
+ }
+ return $lastname . ' ' . $firstname;
+}
+
/** Splits a name into tokens, as used in search_name.
* Used for search_name rebuilding and for queries.
*/
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
+ a.full_name = pd.short_name, a.directory_name = pd.directory_name, a.sort_name = pd.sort_name
WHERE a.uid = {?}",
$uid);
}
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);
- }
- }
-
XDB::execute('UPDATE profile_public_names
- SET particles = {?}, lastname_main = {?}, lastname_marital = {?}, lastname_ordinary = {?},
+ SET 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['lastname_main'], $public_names['lastname_marital'], $public_names['lastname_ordinary'],
$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::$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:
?>
const GROUP_XORG = 'Polytechnique.org';
const GROUP_AX = 'AX';
const GROUP_EP = 'Ecole';
+ const GROUP_FX = 'FX';
// Searches on mutiple fields
const SEARCH_ALL = 'all';
return 'ax';
case self::GROUP_EP:
return 'epletter';
+ case self::GROUP_FX:
+ return 'fxletter';
default:
// Don't display groups NLs on X.org
assert(!$enforce_xnet);
return 'ax/admin';
case self::GROUP_EP:
return 'epletter/admin';
+ case self::GROUP_FX:
+ return 'fxletter/admin';
default:
// Don't display groups NLs on X.org
assert(!$enforce_xnet);
return 'ax/stat';
case self::GROUP_EP:
return 'epletter/stat';
+ case self::GROUP_FX:
+ return 'fxletter/stat';
default:
// Don't display groups NLs on X.org
assert(!$enforce_xnet);
case self::GROUP_XORG:
case self::GROUP_AX:
case self::GROUP_EP:
+ case self::GROUP_FX:
return false;
default:
return true;
static public function get($id)
{
- if (!array_key_exists($id, self::$companies)) {
+ if (!is_null($id) && !array_key_exists($id, self::$companies)) {
self::preload();
}
if (isset(self::$companies[$id])) {
$res = XDB::query("SELECT pd.promo, p.title,
IF (pn.firstname_ordinary = '', UPPER(pn.firstname_main), UPPER(pn.firstname_ordinary)) AS firstname,
IF (pn.lastname_ordinary = '', UPPER(pn.lastname_main), UPPER(pn.lastname_ordinary)) AS lastname,
- UPPER(pje.name), pa.postalText, pa.postal_code, p.email_directory
- FROM (SELECT pa.pid, pa.postalText, pace.long_name AS postal_code
+ UPPER(pje.name), pa.postalText, GROUP_CONCAT(pace.long_name) AS postal_code, p.email_directory
+ FROM (SELECT pa.pid, pa.postalText, pa.jobid, pa.groupid, pa.type, pa.id
FROM profile_addresses AS pa
- LEFT JOIN profile_addresses_components AS pac ON (pa.pid = pac.pid
- AND pa.jobid = pac.jobid
- AND pa.groupid = pac.groupid
- AND pa.type = pac.type)
- LEFT JOIN profile_addresses_components_enum AS pace ON (pac.component_id = pace.id
- AND FIND_IN_SET('postal_code', pace.types))
WHERE pa.pub IN ('public', 'ax') AND FIND_IN_SET('mail', pa.flags) AND pa.pid IN {?}
ORDER BY pa.pid, NOT FIND_IN_SET('current', pa.flags),
- FIND_IN_SET('secondary', pa.flags), pa.type = 'job', pace.long_name IS NULL) AS pa
- INNER JOIN profiles AS p ON (pa.pid = p.pid)
- INNER JOIN profile_display AS pd ON (pd.pid = pa.pid)
- INNER JOIN profile_public_names AS pn ON (pn.pid = pa.pid)
- LEFT JOIN profile_job AS pj ON (pj.pid = pa.pid)
- LEFT JOIN profile_job_enum AS pje ON (pj.jobid = pje.id)
+ FIND_IN_SET('secondary', pa.flags), pa.type = 'job') AS pa
+ INNER JOIN profiles AS p ON (pa.pid = p.pid)
+ INNER JOIN profile_display AS pd ON (pd.pid = pa.pid)
+ INNER JOIN profile_public_names AS pn ON (pn.pid = pa.pid)
+ LEFT JOIN profile_addresses_components AS pac ON (pa.pid = pac.pid
+ AND pa.jobid = pac.jobid
+ AND pa.groupid = pac.groupid
+ AND pa.type = pac.type
+ AND pa.id = pac.id)
+ LEFT JOIN profile_addresses_components_enum AS pace ON (pac.component_id = pace.id
+ AND FIND_IN_SET('postal_code', pace.types))
+
+ LEFT JOIN profile_job AS pj ON (pj.pid = pa.pid
+ AND pj.id = IF(pa.type = 'job', pa.id, NULL))
+ LEFT JOIN profile_job_enum AS pje ON (pj.jobid = pje.id)
GROUP BY pa.pid", $pids);
foreach ($res->fetchAllAssoc() as $item) {
fputcsv($csv, array_map('utf8_decode', $item), ';');
public function id()
{
- return $this->user->id() . '_' . $this->type . '_' . $this->stamp;
+ return str_replace(" ", "_", $this->user->id() . '_' . $this->type . '_' . $this->stamp);
}
// }}}
public $hruid;
public $email;
public $group;
+ public $dim;
public $groups;
public $rules = "Accepter si l'adresse email parait correcte, et pas absurde
// }}}
// {{{ constructor
- public function __construct(User $user, $hruid, $email, $group)
+ public function __construct(User $user, $hruid, $email, $group, $dim)
{
parent::__construct($user, false, 'account');
$this->hruid = $hruid;
$this->email = $email;
$this->group = $group;
+ $this->dim = $dim;
$this->uid = XDB::fetchOneCell('SELECT uid
FROM accounts
WHERE hruid = {?}',
$hruid);
- $this->groups = implode(',', XDB::fetchColumn('SELECT g.nom
- FROM groups AS g
- INNER JOIN group_members AS m ON (g.id = m.asso_id)
- WHERE m.uid = {?}
- ORDER BY g.nom',
- $this->uid));
+ $this->groups = XDB::fetchAllAssoc('SELECT g.nom, g.diminutif
+ FROM groups AS g
+ INNER JOIN group_members AS m ON (g.id = m.asso_id)
+ WHERE m.uid = {?}
+ ORDER BY g.nom',
+ $this->uid);
}
// }}}
private $limit = 50;
public $users;
public $group;
+ public $dim;
public $rules = "Accepter si les adresses email paraissent correctes, et pas
absurdes et si le demandeur est de confiance.";
// }}}
// {{{ constructor
- public function __construct(User $user, array $uids, $group)
+ public function __construct(User $user, array $uids, $group, $dim)
{
parent::__construct($user, false, 'bulkaccounts');
$this->group = $group;
+ $this->dim = $dim;
$this->users = XDB::fetchAllAssoc('SELECT uid, hruid, email
FROM accounts
WHERE uid IN {?}',
'admin/jobs' => $this->make_hook('jobs', AUTH_PASSWD, 'admin,edit_directory'),
'admin/profile' => $this->make_hook('profile', AUTH_PASSWD, 'admin,edit_directory'),
'admin/phd' => $this->make_hook('phd', AUTH_PASSWD, 'admin'),
+ 'admin/name' => $this->make_hook('admin_name', AUTH_PASSWD, 'admin'),
'admin/add_secondary_edu' => $this->make_hook('add_secondary_edu', AUTH_PASSWD, 'admin')
);
}
$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');
- } else {
- $to_update['full_name'] = Post::s('lastname');
- $to_update['directory_name'] = mb_strtoupper(Post::s('lastname'));
+ if (Post::s('type') == 'virtual') {
+ $firstname = '';
}
+ $to_update['full_name'] = build_full_name($firstname, $lastname);
+ $to_update['directory_name'] = build_directory_name($firstname, $lastname);
+ $to_update['sort_name'] = build_sort_name($firstname, $lastname);
}
if (Post::s('display_name') != $user->displayName()) {
$to_update['display_name'] = Post::s('display_name');
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')) {
default:
$page->killError("La formation n'est pas reconnue : " . Env::t('edu_type') . '.');
}
+ $best_domain = XDB::fetchOneCell('SELECT id
+ FROM email_virtual_domains
+ WHERE name = {?}',
+ User::$sub_mail_domains[$type] . Platal::globals()->mail->domain);
XDB::startTransaction();
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 = build_full_name($firstname, $lastname);
+ $directoryName = build_directory_name($firstname, $lastname);
+ $sortName = build_sort_name($firstname, $lastname);
$birthDate = self::formatBirthDate($infos[2]);
if ($type == 'x') {
$xorgId = Profile::getXorgId($infos[4]);
$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, $sortName, $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);
XDB::execute('INSERT INTO accounts (hruid, type, is_admin, state, full_name, directory_name,
- display_name, lastname, firstname, sex)
- VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})',
- $infos['hrid'], $type, 0, 'pending', $fullName, $directoryName,
- $infos[1], $infos[0], $infos[1], $sex);
+ display_name, sort_name, lastname, firstname, sex, best_domain)
+ VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})',
+ $infos['hrid'], $type, 0, 'pending', $fullName, $directoryName, $sortName,
+ $firstname, $lastname, $firstname, $sex, $best_domain);
$uid = XDB::insertId();
XDB::execute('INSERT INTO account_profiles (uid, pid, perms)
VALUES ({?}, {?}, {?})',
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 = build_full_name($firstname, $lastname);
+ $directoryName = build_directory_name($firstname, $lastname);
+ $sortName = build_sort_name($firstname, $lastname);
XDB::execute('INSERT INTO accounts (hruid, type, is_admin, state, email, full_name, directory_name,
- display_name, lastname, firstname, sex)
- VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})',
+ sort_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];
+ $sortName ,$firstname, $lastname, $firstname, $sex);
+ $newAccounts[$infos['hrid']] = $fullName;
}
}
}
}
}
+
+ function handler_admin_name($page, $hruid = null)
+ {
+ $page->changeTpl('admin/admin_name.tpl');
+
+ if (Post::has('id')) {
+ $user = User::get(Post::t('id'));
+ if (is_null($user)) {
+ $page->trigError("L'identifiant donné ne correspond à personne ou est ambigu.");
+ exit();
+ }
+ pl_redirect('admin/name/' . $user->hruid);
+ }
+
+ $user = User::getSilent($hruid);
+ if (!is_null($user)) {
+ require_once 'name.func.inc.php';
+
+ if ($user->hasProfile()) {
+ $name_types = array(
+ 'lastname_main' => 'Nom patronymique',
+ 'lastname_marital' => 'Nom marital',
+ 'lastname_ordinary' => 'Nom usuel',
+ 'firstname_main' => 'Prénom',
+ 'firstname_ordinary' => 'Prénom usuel',
+ 'pseudonym' => 'Pseudonyme'
+ );
+ $names = XDB::fetchOneAssoc('SELECT lastname_main, lastname_marital, lastname_ordinary,
+ firstname_main, firstname_ordinary, pseudonym
+ FROM profile_public_names
+ WHERE pid = {?}',
+ $user->profile()->id());
+ } else {
+ $name_types = array(
+ 'lastname' => 'Nom',
+ 'firstname' => 'Prénom'
+ );
+ $names = XDB::fetchOneAssoc('SELECT lastname, firstname
+ FROM accounts
+ WHERE uid = {?}',
+ $user->id());
+ }
+
+ if (Post::has('correct')) {
+ $new_names = array();
+ $update = true;
+ foreach ($name_types as $key => $fullname) {
+ $new_names[$key] = Post::t($key);
+ if (mb_strtolower($new_names[$key]) != mb_strtolower($names[$key])) {
+ $update = false;
+ }
+ }
+
+ if ($update) {
+ if ($user->hasProfile()) {
+ update_public_names($user->profile()->id(), $new_names);
+ update_display_names($user->profile(), $new_names);
+ } else {
+ $new_names['full_name'] = build_full_name($new_names['firstname'], $new_names['lastname']);
+ $new_names['directory_name'] = build_directory_name($new_names['firstname'], $new_names['lastname']);
+ $new_names['sort_name'] = build_sort_name($new_names['firstname'], $new_names['lastname']);
+ XDB::execute('UPDATE accounts
+ SET lastname = {?}, firstname = {?}, full_name = {?},
+ directory_name = {?}, sort_name = {?}
+ WHERE uid = {?}',
+ $new_names['lastname'], $new_names['firstname'], $new_names['full_name'],
+ $new_names['directory_name'], $new_names['sort_name'], $user->id());
+ }
+ $page->trigSuccess('Mise à jour réussie.');
+ } else {
+ $page->trigError('Seuls des changements de casse sont autorisés ici.');
+ }
+ }
+
+ if ($user->hasProfile()) {
+ $names = XDB::fetchOneAssoc('SELECT lastname_main, lastname_marital, lastname_ordinary,
+ firstname_main, firstname_ordinary, pseudonym
+ FROM profile_public_names
+ WHERE pid = {?}',
+ $user->profile()->id());
+ } else {
+ $names = XDB::fetchOneAssoc('SELECT lastname, firstname
+ FROM accounts
+ WHERE uid = {?}',
+ $user->id());
+ }
+
+ foreach ($names as $key => $name) {
+ $names[$key] = array(
+ 'value' => $name,
+ 'standard' => capitalize_name($name)
+ );
+ $names[$key]['different'] = ($names[$key]['value'] != $names[$key]['standard']);
+ }
+
+ $page->assign('uid', $user->id());
+ $page->assign('hruid', $user->hruid);
+ $page->assign('names', $names);
+ $page->assign('name_types', $name_types);
+ }
+ }
}
// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
$page->assign('nbMissmatchingPromosTotal', $nbMissmatchingPromos);
}
- function handler_names($page, $action = '')
+ private function format($string)
+ {
+ return preg_replace('/(\s+|\-)/', '', $string);
+ }
+
+ private function retrieve_firstnames()
+ {
+ $res = XDB::rawFetchAllAssoc('SELECT p.pid, p.ax_id, p.hrpid,
+ f.prenom, ppn.firstname_initial, ppn.firstname_main, ppn.firstname_ordinary
+ FROM fusionax_anciens AS f
+ INNER JOIN profiles AS p ON (f.ax_id = p.ax_id)
+ INNER JOIN profile_public_names AS ppn ON (p.pid = ppn.pid)
+ WHERE f.prenom NOT IN (ppn.firstname_initial, ppn.firstname_main, ppn.firstname_ordinary)');
+
+ $issues = array();
+ foreach ($res as $item) {
+ if (!($item['firstname_ordinary'] != '' || $item['firstname_main'] != $item['firstname_initial'])) {
+ $ax = $this->format(mb_strtolower(replace_accent($item['prenom'])));
+ $xorg = $this->format(mb_strtolower(replace_accent($item['firstname_main'])));
+ if ($ax != $xorg) {
+ $issues[] = $item;
+ }
+ }
+ }
+
+ return $issues;
+ }
+
+ function handler_names($page, $action = '', $csv = false)
{
$page->changeTpl('fusionax/names.tpl');
if ($action == 'first') {
+ $res = $this->retrieve_firstnames();
+ if ($csv) {
+ pl_cached_content_headers('text/x-csv', 'utf-8', 1, 'firstnames.csv');
+
+ $csv = fopen('php://output', 'w');
+ fputcsv($csv, array('pid', 'ax_id', 'hrpid', 'AX', 'initial', 'principal', 'ordinaire'), ';');
+ foreach ($res as $item) {
+ fputcsv($csv, $item, ';');
+ }
+ fclose($csv);
+ exit();
+ } else {
+ $page->assign('firstnameIssues', $res);
+ }
+ } elseif ($action == 'last' || $action == 'last3' || $action == 'last2' || $action == 'last1') {
+ $ax_patro = "(IF(f.partic_patro, CONCAT(f.partic_patro, CONCAT(' ', f.Nom_patronymique)), f.Nom_patronymique) NOT IN (ppn.lastname_initial, ppn.lastname_main, ppn.lastname_marital, ppn.lastname_ordinary))";
+ $ax_ordinary = "(IF(f.partic_nom, CONCAT(f.partic_nom, CONCAT(' ', f.Nom_usuel)), f.Nom_usuel) NOT IN (ppn.lastname_initial, ppn.lastname_main, ppn.lastname_marital, ppn.lastname_ordinary))";
+ $ax_full = "(f.Nom_complet NOT IN (ppn.lastname_initial, ppn.lastname_main, ppn.lastname_marital, ppn.lastname_ordinary))";
+
+ switch ($action) {
+ case 'last':
+ $where = $ax_patro . ' OR ' . $ax_ordinary . ' OR ' . $ax_full;
+ break;
+ case 'last3':
+ $where = $ax_patro . ' AND ' . $ax_ordinary . ' AND ' . $ax_full;
+ break;
+ case 'last2':
+ $where = '(' . $ax_patro . ' AND ' . $ax_ordinary . ' AND NOT ' . $ax_full . ') OR ('
+ . $ax_patro . ' AND NOT ' . $ax_ordinary . ' AND ' . $ax_full . ') OR ('
+ . 'NOT ' . $ax_patro . ' AND ' . $ax_ordinary . ' AND ' . $ax_full . ')';
+ break;
+ case 'last1':
+ $where = '(' . $ax_patro . ' AND NOT ' . $ax_ordinary . ' AND NOT ' . $ax_full . ') OR ('
+ . 'NOT ' . $ax_patro . ' AND NOT ' . $ax_ordinary . ' AND ' . $ax_full . ') OR ('
+ . 'NOT ' . $ax_patro . ' AND ' . $ax_ordinary . ' AND NOT ' . $ax_full . ')';
+ break;
+ }
+
$res = XDB::rawFetchAllAssoc('SELECT p.pid, p.ax_id, p.hrpid,
- f.prenom, ppn.firstname_initial, ppn.firstname_main, ppn.firstname_ordinary
- FROM fusionax_anciens AS f
- INNER JOIN profiles AS p ON (f.ax_id = p.ax_id)
- INNER JOIN profile_public_names AS ppn ON (p.pid = ppn.pid)
- WHERE f.prenom NOT IN (ppn.firstname_initial, ppn.firstname_main, ppn.firstname_ordinary)');
- $page->assign('firstnameIssues', $res);
- } elseif ($action == 'last') {
- $res = XDB::rawFetchAllAssoc("SELECT p.pid, p.ax_id, p.hrpid,
f.Nom_patronymique, f.Nom_usuel, f.Nom_complet,
ppn.lastname_initial, ppn.lastname_main, ppn.lastname_marital, ppn.lastname_ordinary
FROM fusionax_anciens AS f
INNER JOIN profiles AS p ON (f.ax_id = p.ax_id)
INNER JOIN profile_public_names AS ppn ON (p.pid = ppn.pid)
- WHERE IF(f.partic_patro, CONCAT(f.partic_patro, CONCAT(' ', f.Nom_patronymique)), f.Nom_patronymique) NOT IN (ppn.lastname_initial, ppn.lastname_main, ppn.lastname_marital, ppn.lastname_ordinary)
- AND IF(f.partic_nom, CONCAT(f.partic_nom, CONCAT(' ', f.Nom_usuel)), f.Nom_usuel) NOT IN (ppn.lastname_initial, ppn.lastname_main, ppn.lastname_marital, ppn.lastname_ordinary)
- AND f.Nom_complet NOT IN (ppn.lastname_initial, ppn.lastname_main, ppn.lastname_marital, ppn.lastname_ordinary)");
- $page->assign('lastnameIssues', $res);
+ WHERE ' . $where);
+ if ($csv) {
+ function format($string)
+ {
+ $string = preg_replace('/\-/', ' ', $string);
+ return preg_replace('/\s+/', ' ', $string);
+ }
+
+
+ pl_cached_content_headers('text/x-csv', 'utf-8', 1, 'lastnames.csv');
+
+ $csv = fopen('php://output', 'w');
+ fputcsv($csv, array('pid', 'ax_id', 'hrpid', 'AX patro', 'AX usuel', 'AX complet', 'initial', 'principal', 'marital', 'ordinaire'), ';');
+ foreach ($res as $item) {
+ $ax = array(
+ 'Nom_patronymique' => format(mb_strtolower(replace_accent($item['Nom_patronymique']))),
+ 'Nom_usuel' => format(mb_strtolower(replace_accent($item['Nom_usuel']))),
+ 'Nom_complet' => format(mb_strtolower(replace_accent($item['Nom_complet'])))
+ );
+ $xorg = array(
+ 'lastname_initial' => format(mb_strtolower(replace_accent($item['lastname_initial']))),
+ 'lastname_main' => format(mb_strtolower(replace_accent($item['lastname_main']))),
+ 'lastname_ordinary' => format(mb_strtolower(replace_accent($item['lastname_ordinary'])))
+ );
+
+ if (!in_array($ax['Nom_patronymique'], $xorg) || !in_array($ax['Nom_usuel'], $xorg) || !in_array($ax['Nom_complet'], $xorg)) {
+ fputcsv($csv, $item, ';');
+ }
+ }
+ fclose($csv);
+ exit();
+ } else {
+ $page->assign('lastnameIssues', $res);
+ $page->assign('total', count($res));
+ $page->assign('issuesTypes', array(
+ 'last' => "1, 2 ou 3 noms de l'AX manquant",
+ 'last1' => "1 nom de l'AX manquant",
+ 'last2' => "2 noms de l'AX manquant",
+ 'last3' => "3 noms de l'AX manquant"
+ ));
+ }
} else {
$res = XDB::query('SELECT COUNT(*)
FROM fusionax_anciens AS f
INNER JOIN profiles AS p ON (f.ax_id = p.ax_id)
INNER JOIN profile_public_names AS ppn ON (p.pid = ppn.pid)
WHERE IF(f.partic_patro, CONCAT(f.partic_patro, CONCAT(' ', f.Nom_patronymique)), f.Nom_patronymique) NOT IN (ppn.lastname_initial, ppn.lastname_main, ppn.lastname_marital, ppn.lastname_ordinary)
- AND IF(f.partic_nom, CONCAT(f.partic_nom, CONCAT(' ', f.Nom_usuel)), f.Nom_usuel) NOT IN (ppn.lastname_initial, ppn.lastname_main, ppn.lastname_marital, ppn.lastname_ordinary)
- AND f.Nom_complet NOT IN (ppn.lastname_initial, ppn.lastname_main, ppn.lastname_marital, ppn.lastname_ordinary)");
+ OR IF(f.partic_nom, CONCAT(f.partic_nom, CONCAT(' ', f.Nom_usuel)), f.Nom_usuel) NOT IN (ppn.lastname_initial, ppn.lastname_main, ppn.lastname_marital, ppn.lastname_ordinary)
+ OR f.Nom_complet NOT IN (ppn.lastname_initial, ppn.lastname_main, ppn.lastname_marital, ppn.lastname_ordinary)");
$page->assign('lastnameIssues', $res);
$res = XDB::rawFetchOneCell('SELECT COUNT(*)
INNER JOIN profiles AS p ON (f.ax_id = p.ax_id)
INNER JOIN profile_public_names AS ppn ON (p.pid = ppn.pid)
WHERE f.prenom NOT IN (ppn.firstname_initial, ppn.firstname_main, ppn.firstname_ordinary)');
- $page->assign('firstnameIssues', $res);
+ $page->assign('firstnameIssues', count($this->retrieve_firstnames()));
}
$page->assign('action', $action);
}
--- /dev/null
+<?php
+/***************************************************************************
+ * 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 *
+ ***************************************************************************/
+
+Platal::load('newsletter');
+
+class FXLetterModule extends NewsletterModule
+{
+ function handlers()
+ {
+ return array(
+ 'fxletter' => $this->make_hook('nl', AUTH_COOKIE, 'user'),
+ 'fxletter/out' => $this->make_hook('out', AUTH_PUBLIC),
+ 'fxletter/show' => $this->make_hook('nl_show', AUTH_COOKIE, 'user'),
+ 'fxletter/search' => $this->make_hook('nl_search', AUTH_COOKIE, 'user'),
+ 'fxletter/admin' => $this->make_hook('admin_nl', AUTH_PASSWD, 'user'),
+ 'fxletter/admin/edit' => $this->make_hook('admin_nl_edit', AUTH_PASSWD, 'user'),
+ 'fxletter/admin/edit/valid' => $this->make_hook('admin_nl_valid', AUTH_PASSWD, 'user'),
+ 'fxletter/admin/edit/cancel' => $this->make_hook('admin_nl_cancel', AUTH_PASSWD, 'user'),
+ 'fxletter/admin/edit/delete' => $this->make_hook('admin_nl_delete', AUTH_PASSWD, 'user'),
+ 'fxletter/admin/categories' => $this->make_hook('admin_nl_cat', AUTH_PASSWD, 'user'),
+ 'fxletter/stat' => $this->make_hook('stat_nl', AUTH_PASSWD, 'user')
+ );
+ }
+
+ protected function getNl()
+ {
+ require_once 'newsletter.inc.php';
+ return NewsLetter::forGroup(NewsLetter::GROUP_FX);
+ }
+
+ function handler_out($page, $hash = null, $issue_id = null)
+ {
+ if (!$hash) {
+ if (!S::logged()) {
+ return PL_DO_AUTH;
+ }
+ }
+ return $this->handler_nl($page, 'out', $hash, $issue_id);
+ }
+}
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
public function value(ProfilePage $page, $field, $value, &$success)
{
+ require_once 'name.func.inc.php';
$success = true;
if (is_null($value)) {
$request = NamesReq::getPublicNames($page->pid());
if (!$request) {
- $value['public_names'] = XDB::fetchOneAssoc('SELECT particles, lastname_main, lastname_marital, lastname_ordinary,
+ $value['public_names'] = XDB::fetchOneAssoc('SELECT 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);
- }
} else {
$value['public_names'] = $request;
Platal::page()->assign('validation', true);
$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) {
}
}
- 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']);
$networks[0] = '-';
ksort($networks);
$page->assign('networking_types', $networks);
- $origin_corps_list = DirEnum::getOptions(DirEnum::CURRENTCORPS);
- $current_corps_list = DirEnum::getOptions(DirEnum::ORIGINCORPS);
+ $origin_corps_list = DirEnum::getOptions(DirEnum::ORIGINCORPS);
+ $current_corps_list = DirEnum::getOptions(DirEnum::CURRENTCORPS);
$corps_rank_list = DirEnum::getOptions(DirEnum::CORPSRANKS);
$origin_corps_list[0] = '-';
$current_corps_list[0] = '-';
}
}
+ 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 = build_full_name($firstname, $lastname);
+ $directory_name = build_directory_name($firstname, $lastname);
+ $sort_name = build_sort_name($firstname, $lastname);
XDB::query('UPDATE accounts
- SET full_name = {?}, directory_name = {?}, display_name = {?},
+ SET full_name = {?}, directory_name = {?}, sort_name = {?}, display_name = {?},
firstname = {?}, lastname = {?}, sex = {?}
WHERE uid = {?}',
- $full_name, $directory_name, Post::t('display_name'),
+ $full_name, $directory_name, $sort_name, Post::t('display_name'),
Post::t('firstname'), Post::t('lastname'),
(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
}
// update actual inscriptions
- $updated = false;
- $total = 0;
- $paid = $evt['paid'] ? $evt['paid'] : 0;
- $telepaid= $evt['telepaid'] ? $evt['telepaid'] : 0;
+ $updated = false;
+ $total = 0;
+ $paid = $evt['paid'] ? $evt['paid'] : 0;
+ $telepaid = $evt['telepaid'] ? $evt['telepaid'] : 0;
+ $paid_inserted = false;
foreach ($subs as $j => $nb) {
if ($nb >= 0) {
XDB::execute('INSERT INTO group_event_participants (eid, uid, item_id, nb, flags, paid)
VALUES ({?}, {?}, {?}, {?}, {?}, {?})
ON DUPLICATE KEY UPDATE nb = VALUES(nb), flags = VALUES(flags), paid = VALUES(paid)',
$eid, S::v('uid'), $j, $nb, (Env::has('notify_payment') ? 'notify_payment' : ''),
- ($j == 1 ? $paid - $telepaid : 0));
+ ((!$paid_inserted) ? $paid - $telepaid : 0));
$updated = $eid;
+ $paid_inserted = true;
} else {
XDB::execute(
"DELETE FROM group_event_participants
$amount = strtr(Env::v('montant'), ',', '.');
XDB::execute("UPDATE group_event_participants
SET paid = paid + {?}
- WHERE uid = {?} AND eid = {?} AND item_id = 1",
+ WHERE uid = {?} AND eid = {?} AND nb > 0
+ ORDER BY item_id ASC
+ LIMIT 1",
$amount, $member->uid, $evt['eid']);
subscribe_lists_event($member->uid, $evt['short_name'], 1, $amount);
}
// change the number of personns coming with a participant
if (Env::v('adm') == 'nbs' && $member) {
- $res = XDB::query("SELECT paid
+ $res = XDB::query("SELECT SUM(paid)
FROM group_event_participants
WHERE uid = {?} AND eid = {?}",
$member->uid, $evt['eid']);
- $paid = intval($res->fetchOneCell());
+ $paid = $res->fetchOneCell();
$nbs = Post::v('nb', array());
+ $paid_inserted = false;
foreach ($nbs as $id => $nb) {
$nb = max(intval($nb), 0);
+ if (!$paid_inserted && $nb > 0) {
+ $item_paid = $paid;
+ $paid_inserted = true;
+ } else {
+ $item_paid = 0;
+ }
XDB::execute('INSERT INTO group_event_participants (eid, uid, item_id, nb, flags, paid)
VALUES ({?}, {?}, {?}, {?}, {?}, {?})
ON DUPLICATE KEY UPDATE nb = VALUES(nb), flags = VALUES(flags), paid = VALUES(paid)',
- $evt['eid'], $member->uid, $id, $nb, '', ($id == 1 ? $paid : 0));
+ $evt['eid'], $member->uid, $id, $nb, '', $item_paid);
}
$res = XDB::query('SELECT COUNT(uid) AS cnt, SUM(nb) AS nb
GROUP BY uid',
$member->uid, $evt['eid']);
$u = $res->fetchOneAssoc();
- if ($u['cnt'] == 1 && $paid == 0 && Post::v('cancel')) {
+ if ($paid == 0 && Post::v('cancel')) {
XDB::execute("DELETE FROM group_event_participants
WHERE uid = {?} AND eid = {?}",
$member->uid, $evt['eid']);
if ($m['montant']) {
$evt['money'] = true;
}
- $evt['paid'] = $m['paid'];
+ $evt['paid'] += $m['paid'];
$evt['notify_payment'] = $evt['notify_payment'] || $m['notify_payment'];
}
'%grp/member/new/ajax' => $this->make_hook('admin_member_new_ajax', AUTH_PASSWD, 'groups', NO_AUTH),
'%grp/member/del' => $this->make_hook('admin_member_del', AUTH_PASSWD, 'groupadmin'),
'%grp/member/suggest' => $this->make_hook('admin_member_suggest', AUTH_PASSWD, 'groupadmin'),
+ '%grp/member/reg' => $this->make_hook('admin_member_reg', AUTH_PASSWD, 'groupadmin'),
'%grp/rss' => $this->make_token_hook('rss', AUTH_PUBLIC),
'%grp/announce/new' => $this->make_hook('edit_announce', AUTH_PASSWD, 'groupadmin'),
continue;
}
+ require_once 'name.func.inc.php';
$parts = explode('.', $local_part);
if (count($parts) == 1) {
- $lastname = $display_name = $full_name = $directory_name = ucfirst($local_part);
+ $lastname = $display_name = capitalize_name($mbox);
$firstname = '';
} else {
- $firstname = ucfirst($parts[0]);
- $lastname = ucwords(implode(' ', array_slice($parts, 1)));
- $display_name = $firstname;
- $full_name = $firstname . ' ' . $lastname;
- $directory_name = strtoupper($lastname) . ' ' . $firstname;
+ $display_name = $firstname = capitalize_name($parts[0]);
+ $lastname = capitalize_name(implode(' ', array_slice($parts, 1)));
}
- XDB::execute('INSERT INTO accounts (hruid, display_name, full_name, directory_name, firstname, lastname, email, type, state)
- VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?}, \'xnet\', \'disabled\')',
- $hruid, $display_name, $full_name, $directory_name, $firstname, $lastname, $email);
+ $full_name = build_full_name($firstname, $lastname);
+ $directory_name = build_directory_name($firstname, $lastname);
+ $sort_name = build_sort_name($firstname, $lastname);
+ XDB::execute('INSERT INTO accounts (hruid, display_name, full_name, directory_name, sort_name,
+ firstname, lastname, email, type, state)
+ VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, \'xnet\', \'disabled\')',
+ $hruid, $display_name, $full_name, $directory_name, $sort_name, $firstname, $lastname, $email);
$uid = XDB::insertId();
XDB::execute('INSERT INTO group_members (asso_id, uid)
VALUES ({?}, {?})',
$uids_to_enable = array_intersect(array_keys(Post::v('enable_accounts')), $uids);
$user = S::user();
- $group = Platal::globals()->asso('nom');
- $request = new BulkAccountsReq($user, $uids_to_enable, $group);
+ $request = new BulkAccountsReq($user, $uids_to_enable, $globals->asso('nom'), $globals->asso('diminutif'));
$request->submit();
$page->trigSuccess('Un email va bientôt être envoyé aux personnes sélectionnées pour l\'activation de leur compte.');
global $globals;
$page->changeTpl('xnetgrp/membres-add.tpl');
+ $page->addJsLink('xnet_members.js');
if (is_null($email)) {
return;
XDB::query('UPDATE accounts
SET email = {?}
WHERE uid = {?} AND email IS NULL',
- Post::t('email'), $user->id());
+ $email, $user->id());
// Add email for marketing if required.
- if (Env::v('market')) {
+ if (Env::v('marketing')) {
$market = Marketing::get($user->uid, $email);
if (!$market) {
$market = new Marketing($user->uid, $email, 'group', $globals->asso('nom'),
- Env::v('market_from'), S::v('uid'));
+ Env::v('marketing_from'), S::v('uid'));
$market->add();
}
}
+ } elseif (Env::v('broken')) {
+ // Add email for broken if required.
+ $valid = new BrokenReq(S::user(), $user, $email, 'Groupe : ' . $globals->asso('nom'));
+ $valid->submit();
}
} else {
$user = User::getSilent($email);
// 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 = capitalize_name($mbox);
$firstname = '';
} else {
- $firstname = ucfirst($parts[0]);
- $lastname = ucwords(implode(' ', array_slice($parts, 1)));
- $display_name = $firstname;
- $full_name = "$firstname $lastname";
- $directory_name = strtoupper($lastname) . " " . $firstname;
+ $display_name = $firstname = capitalize_name($parts[0]);
+ $lastname = capitalize_name(implode(' ', array_slice($parts, 1)));
}
- XDB::execute('INSERT INTO accounts (hruid, display_name, full_name, directory_name, firstname, lastname, email, type, state)
- VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?}, \'xnet\', \'disabled\')',
- $hruid, $display_name, $full_name, $directory_name, $firstname, $lastname, $email);
+ $full_name = build_full_name($firstname, $lastname);
+ $directory_name = build_directory_name($firstname, $lastname);
+ $sort_name = build_sort_name($firstname, $lastname);
+ XDB::execute('INSERT INTO accounts (hruid, display_name, full_name, directory_name, sort_name,
+ firstname, lastname, email, type, state)
+ VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, \'xnet\', \'disabled\')',
+ $hruid, $display_name, $full_name, $directory_name, $sort_name, $firstname, $lastname, $email);
$user = User::getSilent($hruid);
}
if (Post::has('suggest')) {
if (Post::t('suggest') == 'yes') {
+ global $globals;
+
$user = S::user();
- $request = new AccountReq($user, $hruid, $email, Platal::globals()->asso('nom'));
+ $request = new AccountReq($user, $hruid, $email, $globals->asso('nom'), $globals->asso('diminutif'));
$request->submit();
$page->trigSuccessRedirect('Un email va bien être envoyé à ' . $email . ' pour l\'activation de son compte.',
- Platal::globals()->asso('diminutif') . '/member/' . $hruid);
+ $globals->asso('diminutif') . '/member/' . $hruid);
} else {
pl_redirect('member/' . $hruid);
}
$page->assign('hruid', $hruid);
}
+ function handler_admin_member_reg($page, $uid)
+ {
+ pl_content_headers('text/plain');
+
+ $user = User::getSilentWithUID($uid);
+ if ($user && $user->state != 'pending' && $user->hasProfile()) {
+ echo true;
+ }
+ echo false;
+ exit();
+ }
+
function handler_admin_member_new_ajax($page)
{
pl_content_headers("text/html");
$page->changeTpl('xnetgrp/membres-new-search.tpl', NO_SKIN);
$users = array();
+ $same_email = false;
if (Env::has('login')) {
$user = User::getSilent(Env::t('login'));
if ($user && $user->state != 'pending') {
- $users = array($user);
+ $users = array($user->id() => $user);
+ $same_email = true;
}
}
if (empty($users)) {
list($lastname, $firstname) = str_replace(array('-', ' ', "'"), '%', array(Env::t('nom'), Env::t('prenom')));
- $cond = new PFC_And(new PFC_Not(new UFC_Registered()));
+ $cond = new PFC_And();
if (!empty($lastname)) {
$cond->addChild(new UFC_NameTokens($lastname, array(), false, false, Profile::LASTNAME));
}
$users = array();
}
}
+
$page->assign('users', $users);
+ $page->assign('same_email', $same_email);
}
function unsubscribe(PlUser $user, $remember = false)
}
}
- private function changeLogin(PlPage $page, PlUser $user, $login)
+ private function changeLogin(PlPage $page, PlUser $user, $login, $req_broken = false, $req_marketing = false, $marketing_from = 'user')
{
// Search the user's uid.
$xuser = User::getSilent($login);
return false;
}
+ // Market or suggest new redirection if required.
+ $email = $user->bestEmail();
+ if ($req_broken) {
+ $valid = new BrokenReq(S::user(), $xuser, $email, 'Groupe : ' . Platal::globals()->asso('nom'));
+ $valid->submit();
+ } elseif ($req_marketing) {
+ $market = Marketing::get($xuser->uid, $email);
+ if (!$market) {
+ $market = new Marketing($xuser->uid, $email, 'group', Platal::globals()->asso('nom'), $marketing_from, S::i('uid'));
+ $market->add();
+ }
+ }
+
if ($user->mergeIn($xuser)) {
return $xuser->login();
}
}
$page->changeTpl('xnetgrp/membres-edit.tpl');
+ $page->addJsLink('xnet_members.js');
$mmlist = new MMList(S::user(), $globals->asso('mail_domain'));
if (Post::has('change')) {
- require_once 'emails.inc.php';
S::assert_xsrf_token();
+ require_once 'emails.inc.php';
+ require_once 'name.func.inc.php';
// Convert user status to X
- if (!Post::blank('login_X')) {
- $forlife = $this->changeLogin($page, $user, Post::t('login_X'));
+ if (!Post::blank('x')) {
+ $forlife = $this->changeLogin($page, $user, Post::i('userid'), Post::b('broken'), Post::b('marketing'), Post::v('marketing_from'));
if ($forlife) {
pl_redirect('member/' . $forlife);
}
// 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');
- $full_name = $firstname . ' ' . $lastname;
- $directory_name = mb_strtoupper($lastname) . ' ' . $firstname;
+ $firstname = capitalize_name(Post::t('firstname'));
} else {
$firstname = '';
- $full_name = $lastname;
- $directory_name = mb_strtoupper($lastname);
}
+ $full_name = build_full_name($firstname, $lastname);
+ $directory_name = build_directory_name($firstname, $lastname);
+ $sort_name = build_sort_name($firstname, $lastname);
XDB::query('UPDATE accounts
- SET full_name = {?}, directory_name = {?}, display_name = {?},
+ SET full_name = {?}, directory_name = {?}, sort_name = {?}, display_name = {?},
firstname = {?}, lastname = {?}, sex = {?}, type = {?}
WHERE uid = {?}',
- $full_name, $directory_name, Post::t('display_name'), $firstname, $lastname,
+ $full_name, $directory_name, $sort_name, Post::t('display_name'), $firstname, $lastname,
(Post::t('sex') == 'male') ? 'male' : 'female',
(Post::t('type') == 'xnet') ? 'xnet' : 'virtual', $user->id());
}
if (($user->type == 'xnet' && !$user->perms)) {
if (Post::b('suggest')) {
- $request = new AccountReq(S::user(), $user->hruid, Post::t('email'), $globals->asso('nom'));
+ $request = new AccountReq(S::user(), $user->hruid, Post::t('email'), $globals->asso('nom'), $globals->asso('diminutif'));
$request->submit();
$page->trigSuccess('Le compte va bientôt être activé.');
}
$map = "<a href=\"http://maps.google.fr/?q="
. urlencode(implode(", ", $lines) . " ($idt)")
. "\"><img src=\"images/icons/map.gif\" alt=\"Google Maps\" title=\"Carte\"/></a>";
+ if ($adr->flags->hasflag('mail')) {
+ $mail = ' <img src="images/icons/email_open.gif" alt="Adresse courier" title="On peut lui envoyer du courier à cette adresse." />';
+ } else {
+ $mail = '';
+ }
$comment = "";
if ($adr->comment != "")
{
if ($param['titre'])
{
if ($param['titre_div'])
- $txthtml .= "<div class='titre'>".pl_entity_decode($param['titre'])." ".$map.$comment."</div>\n";
+ $txthtml .= '<div class="titre">' . pl_entity_decode($param['titre']) . ' ' . $map . $mail . $comment . "</div>\n";
else
- $txthtml .= "<em>".pl_entity_decode($param['titre'])." </em>".$map.$comment."<br />\n";
+ $txthtml .= '<em>' . pl_entity_decode($param['titre']) . ' </em>' . $map . $mail . $comment . "<br />\n";
}
foreach ($lines as $line)
{
--- /dev/null
+{**************************************************************************}
+{* *}
+{* 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 *}
+{* *}
+{**************************************************************************}
+
+<h1>Gestion des noms{if t($hruid)} de {profile user=$uid promo=true directory=false}{/if}</h1>
+
+{if t($hruid)}
+<form method="post" action="{$platal->ns}admin/name/{$hruid}">
+ <table class="bicol">
+ <tr>
+ <th></th>
+ <th>Version actuelle</th>
+ <th>Version suggérée</th>
+ </tr>
+ {foreach from=$names item=name key=type}
+ <tr>
+ <th>{$name_types.$type}</th>
+ <td><input type="text" size="40" name="{$type}" value="{$name.value}" {if $name.different}class="warning"{/if} /></td>
+ <td>{$name.standard}</td>
+ </tr>
+ {/foreach}
+ </table>
+ <p class="center">
+ <input type="submit" name="correct" value="Corriger" />
+ </p>
+</form>
+<p>
+ <a href="admin/name">Retour à la gestion des noms.</a>
+</p>
+{else}
+<form method="post" action="{$platal->ns}admin/name">
+ <p>
+ Il est possible d'entrer ici n'importe quelle adresse email : redirection, melix ou alias.<br />
+ <input type="text" size="60" name="id" />
+ <input type="submit" value="Chercher" />
+ </p>
+</form>
+{/if}
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
<a href="admin/homonyms">Homonymes</a>
|
<a href="admin/deaths">Décès</a>
+ |
+ <a href="admin/name">Noms</a>
</td>
</tr>
<tr class="pair">
{if $firstnameIssues|@count eq 0}
<p>Aucun problème avec les prénoms.</p>
{else}
+<p><a href="fusionax/names/first/true">Obtenir le csv des conflits.</a></p>
<table class="bicol">
<tr>
<th>pid</th>
{/foreach}
</table>
{/if}
-{elseif $action eq "last"}
+{elseif $action eq "last" || $action eq "last1" || $action eq "last2" || $action eq "last3"}
+<h3>{$issuesTypes.$action} : {$total}</h3>
+<ul>
+ <li><a href="fusionax/names/last">{$issuesTypes.last}.</a></li>
+ <li><a href="fusionax/names/last1">{$issuesTypes.last1}.</a></li>
+ <li><a href="fusionax/names/last2">{$issuesTypes.last2}.</a></li>
+ <li><a href="fusionax/names/last3">{$issuesTypes.last3}.</a></li>
+</ul>
{if $lastnameIssues|@count eq 0}
-<p>Aucun problème avec les noms.</p>
+<p>Aucun problème de ce type avec les noms.</p>
{else}
+<p><a href="fusionax/names/last/true">Obtenir le csv des conflits.</a></p>
<table class="bicol">
<tr>
<th>pid</th>
<tr class="pair">
<td class="titre">Groupe demandeur :</td>
- <td>{$valid->group}</td>
+ <td><a href="http://polytechnique.net/{$valid->dim}">{$valid->group}</a></td>
</tr>
<tr class="pair">
<td class="titre">Tous les groupes :</td>
- <td>{$valid->groups}</td>
+ <td>
+ {foreach from=$valid->groups item=group}
+ <a href="http://polytechnique.net/{$group.diminutif}">{$group.nom}</a>
+ {/foreach}
+ </td>
</tr>
<tr class="pair">
<td class="titre">Adresse email :</td>
<tr class="pair">
<td class="titre">Groupe demandeur :</td>
- <td>{$valid->group}</td>
+ <td><a href="http://polytechnique.net/{$valid->dim}">{$valid->group}</a></td>
</tr>
<tr class="pair">
<td class="titre">Adresses emails :</td>
--- /dev/null
+{**************************************************************************}
+{* *}
+{* 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 *}
+{* *}
+{**************************************************************************}
+
+{config_load file="mails.conf" section="mails_fx"}
+{if $mail_part eq 'head'}
+{from full=#from#}
+{subject text=$issue->title(true)}
+{if isset(#replyto#)}{add_header name='Reply-To' value=#replyto#}{/if}
+{if isset(#retpath#)}{add_header name='Return-Path' value=#retpath#}{/if}
+{elseif $mail_part eq 'text'}
+{if !$is_mail}
+<pre style="width : 72ex; margin: auto">
+{/if}
+====================================================================
+{$issue->title()}
+====================================================================
+
+{$issue->head($user, 'text')}
+
+{$issue->signature('text')}
+
+--------------------------------------------------------------------
+{if $is_mail}
+Pour faire un don : <http://fondationx.fr/fond/paiement.php>
+{else}
+Pour faire un don : <http://fondationx.fr/fond/paiement.php>
+{/if}
+Cette lettre est envoyée par la FX grâce aux outils de Polytechnique.org.
+
+{if $is_mail}
+archives : <https://www.polytechnique.org/fxletter>
+ne plus recevoir : <https://www.polytechnique.org/fxletter/out/{if $hash}{$hash}{else}nohash{/if}/{$issue->id}>
+{else}
+archives : <https://www.polytechnique.org/fxletter>
+ne plus recevoir : <https://www.polytechnique.org/fxletter/out/{if $hash}{$hash}{else}nohash{/if}/{$issue->id}>
+{/if}
+
+{if !$is_mail}
+</pre>
+{/if}
+{elseif $mail_part eq 'html'}
+{if $is_mail}
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>Lettre d'information de la Fondation de l'École polytechnique</title>
+ <style type="text/css">
+ {literal}
+ body { background-color: #ddd; color: #000; }
+ {/literal}
+ <!--
+ {$issue->css()}
+ -->
+ </style>
+ </head>
+ <body>
+ <div class="fx_background">
+{/if}
+ <div class='fx_mail'>
+ <div class="title">{$issue->title()}</div>
+ <div class="intro">{$issue->head($user, 'html')|smarty:nodefaults}</div>
+ <div class="signature">{$issue->signature('html')|smarty:nodefaults}</div>
+ <div class="give"><a href="http://fondationx.fr/fond/paiement.php">Faire un don</a></div>
+ <div class="foot1">
+ Cette lettre est envoyée par la FX grâce aux outils de Polytechnique.org.
+ </div>
+ <div class="foot2">
+ [<a href="https://www.polytechnique.org/fxletter">archives</a> |
+ <a href="https://www.polytechnique.org/fxletter/out/{if $hash}{$hash}{else}nohash{/if}/{$issue->id}">ne plus recevoir</a>]
+ </div>
+ </div>
+{if $is_mail}
+ </div>
+ </body>
+</html>
+{/if}
+{/if}
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
</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>
+ <td></td>
</tr>
{/foreach}
<td></td>
</tr>
{/if}
- <tr class="names_advanced" {if !$errors.search_names}style="display: none"{/if}>
+ <tr class="names_advanced_public" {if !$errors.search_names}style="display: none"{/if}>
<td colspan="3">
<span class="titre">Gestion des noms, prénoms, surnoms...</span>
<span class="smaller">Ils déterminent la façon dont
</div>
</td>
</tr>
+ <tr class="names_advanced_private" {if !$errors.search_names}style="display: none"{/if}>
+ <td class="center" colspan="2">
+ <small>Si la casse de ton nom est erronée et que tu n'arrives pas à la corriger,
+ <a href="mailto:support@{#globals.mail.domain#}">contacte-nous</a>.</small>
+ </td>
+ </tr>
</table>
<table class="bicol" style="margin-bottom: 1em"
<div class="menu_item"><a href="nl">Lettres mensuelles</a></div>
<div class="menu_item"><a href="ax">Lettres de l'AX</a></div>
<div class="menu_item"><a href="epletter">Lettres de l'École</a></div>
+<div class="menu_item"><a href="fxletter">Lettres de la FX</a></div>
<div class="menu_item"><a href="Xorg/NousContacter">Nous contacter</a></div>
<div class="menu_item"><a href="send_bug/{ $smarty.server.REQUEST_URI }" class="popup2">Signaler un bug</a></div>
--- /dev/null
+{**************************************************************************}
+{* *}
+{* 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>
+ <td colspan="2">
+ <input type="checkbox" id="x" name="x" onchange="xStateChange(this, '{$platal->ns}');" />
+ <label for="x">Coche cette case s'il s'agit d'un X ou un master ou doctorant de l'X non inscrit à Polytechnique.org.</label>
+ </td>
+</tr>
+<tr class="details" style="display: none">
+ <td class="titre">Nom :</td>
+ <td><input type="text" id="nom" name="nom" size="20" value="" onkeyup="searchX('{$platal->ns}');" /></td>
+</tr>
+<tr class="details" style="display: none">
+ <td class="titre">Prénom :</td>
+ <td><input type="text" id="prenom" name="prenom" size="20" value="" onkeyup="searchX('{$platal->ns}');" /></td>
+</tr>
+<tr class="details" style="display: none">
+ <td class="titre">Promotion :</td>
+ <td><input type="text" id="promo" name="promo" size="4" value="" onkeyup="searchX('{$platal->ns}');" /> <small>(X2004)</small></td>
+</tr>
+<tr class="details pair" style="display: none">
+ <td colspan="2" id="search_result">
+ {include file="xnetgrp/membres-new-search.tpl"}
+ </td>
+</tr>
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
{* *}
{**************************************************************************}
-<script type="text/javascript">//<![CDATA[
-{literal}
-function xStateChange(box)
-{
- var state = (box.checked ? '' : 'none');
- document.getElementById('xnom').style.display = state;
- document.getElementById('xprenom').style.display = state;
- document.getElementById('xpromo').style.display = state;
- document.getElementById('xsearch').style.display = state;
- $('#search_result').updateHtml('{/literal}{$platal->ns}{literal}member/new/ajax?login='
- + $('#email').val());
-}
-
-var nom;
-var prenom;
-var promo;
-function searchX()
-{
- if (document.getElementById('nom').value == nom
- && document.getElementById('prenom').value == prenom
- && document.getElementById('promo').value == promo) {
- return;
- }
- var nom = document.getElementById('nom').value;
- var prenom = document.getElementById('prenom').value;
- var promo = document.getElementById('promo').value;
- $('#search_result').updateHtml('{/literal}{$platal->ns}{literal}member/new/ajax?prenom=' + prenom + '&nom=' + nom + '&promo=' + promo);
-}
-{/literal}
-//]]></script>
-
<h1>{$asso->nom} : Ajout d'un membre</h1>
<form method="post" action="{$platal->ns}member/new/">
onclick='this.form.action += this.form.email.value' />
</td>
</tr>
- <tr>
- <td colspan="2">
- <input type="checkbox" id="x" name="x" onchange="xStateChange(this);" />
- {* TODO: adapts text for masters and doctorates when required. *}
- <label for="x">Coche cette case s'il s'agit d'un X ou un master ou doctorant de l'X non inscrit à Polytechnique.org.</label>
- </td>
- </tr>
- <tr id="xnom" style="display: none">
- <td class="titre">Nom :</td>
- <td><input type="text" id="nom" name="nom" size="20" value="" onkeyup="searchX();" /></td>
- </tr>
- <tr id="xprenom" style="display: none">
- <td class="titre">Prénom :</td>
- <td><input type="text" id="prenom" name="prenom" size="20" value="" onkeyup="searchX();" /></td>
- </tr>
- <tr id="xpromo" style="display: none">
- <td class="titre">Promotion :</td>
- {* TODO: add examples for masters and doctorates when required. *}
- <td><input type="text" id="promo" name="promo" size="4" value="" onkeyup="searchX();" /> <small>(X2004)</small></td>
- </tr>
- <tr id="xsearch" style="display: none" class="pair">
- <td colspan="2" id="search_result">
- {include file="xnetgrp/membres-new-search.tpl"}
- </td>
- </tr>
+ {include file="xnetgrp/members_new_form.tpl" registered=false}
</table>
</form>
-
{literal}
<script type="text/javascript">
$("#email").focus();
var state = (box.value != 'virtual') ? '' : 'none';
document.getElementById('prenom').style.display = state;
document.getElementById('sexe').style.display = state;
- document.getElementById('make_X').style.display = state;
document.getElementById('password').style.display = state;
}
-
- function showXInput(box)
- {
- if (box.checked) {
- document.getElementById('make_X_cb').style.display = 'none';
- document.getElementById('make_X_login').style.display = '';
- }
- }
{/literal}
</script>
<h2>
Édition du profil de {profile user=$user groupperms=false sex=false promo=true}
+ {if $user->bestEmail()}
<a href="mailto:{$user->bestEmail()}">{icon name=email title="mail"}</a>
+ {/if}
</h2>
+{if $user->type eq 'x' || $user->type eq 'master' || $user->type eq 'phd'}
+{if $user->state eq 'pending'}
+<p>
+ {"Ce"|sex:"Cette":$user} camarade n'est pas {"inscrit"|sex:"inscrite":$user}.
+ <a href="{$globals->xnet->xorg_baseurl}marketing/public/{$user->login()}" class='popup'>Si tu connais son adresse email,
+ <strong>n'hésite pas à nous la transmettre !</strong>
+ </a>
+</p>
+{elseif $user->state neq 'disabled' && $user->lost}
+<p>
+ {"Ce"|sex:"Cette":$user} camarade n'a plus d'adresse de redirection valide.
+ <a href="{$globals->xnet->xorg_baseurl}marketing/broken/{$user->login()}">
+ Si tu en connais une, <strong>n'hésite pas à nous la transmettre</strong>.
+ </a>
+</p>
+{/if}
+{/if}
+
<form method="post" action="{$platal->ns}member/{$platal->argv[1]}">
{xsrf_token_field}
<table cellpadding="0" cellspacing="0" class='tinybicol'>
</tr>
{/if}
{if $user->type eq 'xnet'}
- <tr id="make_X">
- <td colspan="2">
- <span id="make_X_cb">
- <input type="checkbox" name="is_x" id="is_x" onclick="showXInput(this);" onchange="showXInput(this);" />
- <label for="is_x">coche cette case s'il s'agit d'un X ou un master ou doctorant de l'X</label>
- </span>
- <span id="make_X_login" style="display: none">
- <span class="titre">Identifiant (prenom.nom.promo) :</span>
- <input type="text" name="login_X" value="" />
- </span>
- </td>
- </tr>
+ {include file="xnetgrp/members_new_form.tpl" registered=true}
{/if}
{if $user->type eq 'xnet' && $suggest}
<tr>
{/if}
</table>
+ {if $user->bestEmail()}
<h2>Abonnement aux listes</h2>
<table cellpadding="0" cellspacing="0" class='large'>
<tr><td colspan='2'>Pas d'alias pour ce groupe</td></tr>
{/foreach}
</table>
+ {else}
+ <p>Cette personne n'a pas d'email renseigné sur le site et ne peut donc pas être inscrite aux listes de diffusions et aux alias du groupe.</p>
+ {/if}
<div class="center">
<br />
{* *}
{**************************************************************************}
- {if t($too_many)}
- Les critères de recherche ne sont pas assez précis.
- {elseif !t($users) || $users|@count eq 0}
- Aucun camarade non-inscrit ne correspond aux informations fournies.
- {else}
- Camarades correspondants :
- <select name="userid" onchange="document.getElementById('marketing').style.display = (this.value == 0 ? 'none' : '')">
- <option value="0"> </option>
- {foreach item=user from=$users}
- <option value="{$user->id()}" {if $users|@count == 1}selected="selected"{/if}>{profile user=$user link=false promo=true}</option>
- {/foreach}
+{if t($too_many)}
+Les critères de recherche ne sont pas assez précis.
+{elseif !t($users) || $users|@count eq 0}
+Aucun camarade non-inscrit ne correspond aux informations fournies.
+{else}
+Camarades correspondants :
+<select name="userid" onchange="updateSuggestions('{$platal->ns}', this.value)">
+ <option value="0" {if $users|@count neq 1}selected="selected"{/if}> </option>
+ {foreach item=user from=$users}
+ <option value="{$user->id()}" {if $users|@count == 1}selected="selected"{/if}>{profile user=$user link=false promo=true}</option>
+ {/foreach}
+</select>
+{if !$same_email}
+<span id="marketing" style="display: none"><br />
+ <label>
+ <input type="checkbox" name="marketing" onchange="$('#marketing_from').toggle()" />
+ Lui envoyer un marketing
+ </label>
+ <select name="marketing_from" id="marketing_from">
+ <option value="user" selected="selected">de ta part.</option>
+ <option value="staff">de la part de Polytechnique.org.</option>
</select>
- <span id="marketing" {if $users|@count != 1}style="display: none"{/if}><br />
- <label><input type="checkbox" name="market" checked="checked"
- onchange="document.getElementById('from').style.display = (this.checked ? '' : 'none')"/>
- Lui envoyer un marketing</label>
- <select name="market_from" id="from">
- <option value="user" selected="selected">de ta part.</option>
- <option value="staff">de la part de Polytechnique.org.</option>
- </select>
- </span>
- {/if}
+</span>
+<span id="broken" style="display: none"><br />
+ Ce camarade est inscrit, mais l'email fourni ne fait pas partie de ses adresses de redirection.<br />
+ <label>
+ <input type="checkbox" name="broken" />
+ Lui suggérer d'ajouter cette adresse email à ses redirections.
+ </label>
+</span>
+{/if}
+{/if}
{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
XDB::rawExecute('ALTER TABLE geoloc_countries ADD INDEX (licensePlate)');
XDB::rawExecute('UPDATE profiles AS p
INNER JOIN fusionax_anciens AS f ON (p.pid = f.pid)
- INNER JOIN geoloc_countries AS g ON (g.licensePlate = f.Code_nationalite AND g.nationalityFR IS NOT NULL)
+ INNER JOIN geoloc_countries AS g ON (g.licensePlate = f.Code_nationalite AND g.nationality IS NOT NULL)
SET p.nationality1 = g.iso_3166_1_a2
WHERE p.nationality1 IS NULL');
XDB::rawExecute('UPDATE profiles AS p
INNER JOIN fusionax_anciens AS f ON (p.pid = f.pid)
- INNER JOIN geoloc_countries AS g ON (g.licensePlate = f.Code_nationalite AND g.nationalityFR IS NOT NULL)
+ INNER JOIN geoloc_countries AS g ON (g.licensePlate = f.Code_nationalite AND g.nationality IS NOT NULL)
SET p.nationality2 = g.iso_3166_1_a2
WHERE p.nationality1 != g.iso_3166_1_a2 AND p.nationality2 IS NULL');
XDB::rawExecute('UPDATE profiles AS p
INNER JOIN fusionax_anciens AS f ON (p.pid = f.pid)
- INNER JOIN geoloc_countries AS g ON (g.licensePlate = f.Code_nationalite AND g.nationalityFR IS NOT NULL)
+ INNER JOIN geoloc_countries AS g ON (g.licensePlate = f.Code_nationalite AND g.nationality IS NOT NULL)
SET p.nationality3 = g.iso_3166_1_a2
WHERE p.nationality1 != g.iso_3166_1_a2 AND p.nationality2 != g.iso_3166_1_a2 AND p.nationality3 IS NULL');
XDB::rawExecute('ALTER TABLE geoloc_countries DROP INDEX licensePlate');
WHERE f.Mel_publiable = 1 AND f.Mel_usage != '' AND p.email_directory IS NULL");
XDB::rawExecute("INSERT IGNORE INTO register_marketing (uid, email, type)
SELECT ap.uid, f.Mel_usage, 'ax'
- FROM fusionax_anciens AS f
- INNER JOIN account_profiles AS ap ON (ap.pid = f.pid AND FIND_IN_SET('owner', perms))
- LEFT JOIN emails AS e ON (e.uid = ap.uid AND e.flags = 'active')
+ FROM fusionax_anciens AS f
+ INNER JOIN account_profiles AS ap ON (ap.pid = f.pid AND FIND_IN_SET('owner', perms))
+ LEFT JOIN email_redirect_account AS e ON (e.uid = ap.uid AND e.flags = 'active')
WHERE f.Mel_usage != '' AND f.Mel_usage NOT LIKE '%@polytechnique.edu'
AND f.Mel_usage NOT LIKE '%@polytechnique.org' AND f.Mel_usage NOT LIKE '%@m4x.org'
- AND f.Mel_usage NOT LIKE '%@melix.%' AND e.email IS NULL");
+ AND f.Mel_usage NOT LIKE '%@melix.%' AND e.redirect IS NULL");
// Retrieves different deathdates.
XDB::rawExecute("UPDATE profile_merge_issues AS pm
--- /dev/null
+#!/usr/bin/php5 -q
+<?php
+/***************************************************************************
+ * 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 *
+ ***************************************************************************/
+
+require '../../bin/connect.db.inc.php';
+
+$globals->debug = 0; // Do not store backtraces
+
+
+$res = XDB::iterator("SELECT p.pid, p.ax_id, p.hrpid,
+ f.Nom_patronymique, f.Nom_usuel, f.Nom_complet,
+ ppn.lastname_initial, ppn.lastname_main, ppn.lastname_marital, ppn.lastname_ordinary
+ FROM fusionax_anciens AS f
+ INNER JOIN profiles AS p ON (f.ax_id = p.ax_id)
+ INNER JOIN profile_public_names AS ppn ON (p.pid = ppn.pid)
+ ORDER BY pid");
+
+function format($string)
+{
+ $string = preg_replace('/\-/', ' ', $string);
+ return preg_replace('/\s+/', ' ', $string);
+}
+
+$updates_count = 0;
+$count = 0;
+$total = $res->total();
+while ($item = $res->next()) {
+ array_map('trim', $item);
+ $ax_plain = array(
+ 'Nom_patronymique' => mb_strtolower(replace_accent($item['Nom_patronymique'])),
+ 'Nom_usuel' => mb_strtolower(replace_accent($item['Nom_usuel'])),
+ 'Nom_complet' => mb_strtolower(replace_accent($item['Nom_complet']))
+ );
+ $ax = array();
+ foreach ($ax_plain as $key => $value) {
+ $ax[$key] = format($value);
+ }
+ $xorg = array(
+ 'lastname_initial' => format(mb_strtolower(replace_accent($item['lastname_initial']))),
+ 'lastname_main' => format(mb_strtolower(replace_accent($item['lastname_main']))),
+ 'lastname_ordinary' => format(mb_strtolower(replace_accent($item['lastname_ordinary'])))
+ );
+
+ foreach ($xorg as $key => $name) {
+ $ax_key = array_search($name, $ax);
+ if ($ax_key !== false && mb_strtolower($item[$ax_key]) != mb_strtolower($item[$key]) && $ax_plain[$ax_key] == mb_strtolower($item[$key])) {
+ XDB::execute("UPDATE profile_public_names
+ SET $key = {?}
+ WHERE pid = {?}",
+ $item[$ax_key], $item['pid']);
+
+ ++$updates_count;
+ }
+ }
+
+ printf("\r%u / %u", $count, $total);
+ ++$count;
+}
+printf("\r%u / %u\n\n", $count, $total);
+
+echo "Nombre de mises à jour effectuées : " . $updates_count . ".\n";
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
require_once 'connect.db.inc.php';
require_once '../../classes/phone.php';
require_once '../../classes/address.php';
+require_once '../../classes/visibility.php';
$globals->debug = 0; // Do not store backtraces.
$duplicates = array();
foreach ($pids as $pid) {
$count = 0;
- $it = Address::iterate(array($pid), array(Address::LINK_PROFILE), array(0));
+ $it = Address::iterate(array($pid), array(Address::LINK_PROFILE), array(0), Visibility::get(Visibility::VIEW_PRIVATE));
while ($item = $it->next()) {
$addresses[$count] = $item;
$rawAddress = preg_replace('/[^a-z0-9]/', ' ', mb_strtolower(replace_accent($item->text)));
for ($j = $i + 1; $j < $count; ++$j) {
if (check($rawAddresses[$i], $rawAddresses[$j])) {
$duplicates[$j] = true;
- $minPub = new ProfileVisibility($addresses[$j]->pub);
- if ($minPub->isVisible($addresses[$i]->pub)) {
+ if (Visibility::isLessRestrictive($addresses[$i]->pub, $addresses[$j]->pub)) {
$addresses[$i]->pub = $addresses[$j]->pub;
}
if ($addresses[$j]->hasFlag('mail') && !$addresses[$i]->hasFlag('mail')) {
}
}
}
- foreach ($duplicates as $key => $bool) {
- unset($addresses[$key]);
+ if (count($duplicates)) {
+ foreach ($duplicates as $key => $bool) {
+ unset($addresses[$key]);
+ }
}
if (count($addresses) != $count) {
$deleted += ($count - count($addresses));
$duplicates = array();
foreach ($pids as $pid) {
$count = 0;
- $it = Phone::iterate(array($pid), array(Phone::LINK_PROFILE), array(0));
+ $it = Phone::iterate(array($pid), array(Phone::LINK_PROFILE), array(0), Visibility::get(Visibility::VIEW_PRIVATE));
while ($item = $it->next()) {
$phones[] = $item;
++$count;
}
for ($i = 0; $i < $count; ++$i) {
for ($j = $i + 1; $j < $count; ++$j) {
- if ($phones[$i]->search() == $phones[$j]->search()) {
+ if ($phones[$i]->search == $phones[$j]->search) {
$duplicates[$j] = true;
- $minPub = new ProfileVisibility($phones[$j]->pub);
- if ($minPub->isVisible($phones[$i]->pub)) {
+ if (Visibility::isLessRestrictive($phones[$i]->pub, $phones[$j]->pub)) {
$phones[$i]->pub = $phones[$j]->pub;
}
-
}
}
}
- foreach ($duplicates as $key => $bool) {
- unset($phones[$key]);
+ if (count($duplicates)) {
+ foreach ($duplicates as $key => $bool) {
+ unset($phones[$key]);
+ }
}
if (count($phones) != $count) {
$deleted += ($count - count($phones));
+++ /dev/null
-#!/usr/bin/php5
-<?php
-// WARNING: this script takes a few weeks to be executed completly, thus run it into a screen.
-
-require_once 'connect.db.inc.php';
-require_once '../../classes/address.php';
-
-$globals->debug = 0; // Do not store backtraces.
-
-print "Tries to geocode addresses (due a bug in the previous release, all addresses must run once again).\n";
-$time = XDB::fetchOneCell('SELECT COUNT(distinct(pid), jobid)
- FROM profile_addresses
- WHERE accuracy IS NOT NULL AND accuracy > 0');
-$time = ceil($time / 60 / 24);
-print "It will approximately take $time days.\n";
-
-$it = XDB::rawIterator('SELECT *
- FROM profile_addresses
- WHERE accuracy IS NOT NULL AND accuracy > 0
- ORDER BY pid, jobid, type, id');
-$total = $it->total();
-$i = 0;
-printf("\r%u / %u", $i, $total);
-$pid = 0;
-$jobid = 0;
-while ($item = $it->next()) {
- $address = new Address($item);
- $address->format(array('requireGeocoding' => true, 'stripGeocoding' => true));
- $address->delete();
- $address->save();
- if (!($pid == $address->pid && $jobid == $address->jobid)) {
- $pid = $address->pid;
- $jobid = $address->jobid;
- sleep(60);
- }
-
- ++$i;
- printf("\r%u / %u", $i, $total);
-}
-print "\nGeocoding done.\n\n";
-print "That's all folks!\n";
-
-/* vim:set et sw=4 sts=4 ts=4: */
-?>
--- /dev/null
+#!/usr/bin/php5 -q
+<?php
+/***************************************************************************
+ * 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 *
+ ***************************************************************************/
+
+require '../../bin/connect.db.inc.php';
+
+$globals->debug = 0; // Do not store backtraces
+
+$res = XDB::rawFetchAllAssoc("SELECT p.pid, p.ax_id, p.hrpid,
+ f.Nom_patronymique, f.Nom_usuel, f.Nom_complet,
+ ppn.lastname_initial, ppn.lastname_main, ppn.lastname_marital, ppn.lastname_ordinary
+ FROM fusionax_anciens AS f
+ INNER JOIN profiles AS p ON (f.ax_id = p.ax_id)
+ INNER JOIN profile_public_names AS ppn ON (p.pid = ppn.pid)
+ WHERE IF(f.partic_patro, CONCAT(f.partic_patro, CONCAT(' ', f.Nom_patronymique)), f.Nom_patronymique) NOT IN (ppn.lastname_initial, ppn.lastname_main, ppn.lastname_marital, ppn.lastname_ordinary)
+ OR IF(f.partic_nom, CONCAT(f.partic_nom, CONCAT(' ', f.Nom_usuel)), f.Nom_usuel) NOT IN (ppn.lastname_initial, ppn.lastname_main, ppn.lastname_marital, ppn.lastname_ordinary)
+ OR f.Nom_complet NOT IN (ppn.lastname_initial, ppn.lastname_main, ppn.lastname_marital, ppn.lastname_ordinary)");
+
+function fix_ax_particles($ax, $xorg, $item)
+{
+ $count = 0;
+ foreach ($ax as $ax_key => $ax_name) {
+ if (!in_array($ax_name, $xorg)) {
+ $new_name = '';
+ foreach ($xorg as $xorg_key => $xorg_name) {
+ if ($xorg_name && strpos($xorg_name, $ax_name) !== false) {
+ if ($xorg_name == 'de ' . $ax_name) {
+ $new_name = 'de ' . $item[$ax_key];
+ } elseif ($xorg_name == "d'" . $ax_name) {
+ $new_name = "d'" . $item[$ax_key];
+ } elseif ($xorg_name == 'du ' . $ax_name) {
+ $new_name = 'du ' . $item[$ax_key];
+ }
+
+ if ($new_name) {
+ XDB::execute("UPDATE fusionax_anciens
+ SET $ax_key = {?}
+ WHERE ax_id = {?}",
+ $new_name, $item['ax_id']);
+ ++$count;
+ break;
+ }
+ }
+ }
+ if ($new_name) {
+ continue;
+ }
+ foreach ($ax as $ax_key2 => $ax_name2) {
+ if ($ax_name2 && strpos($ax_name2, $ax_name) !== false) {
+ if ($ax_name2 == 'de ' . $ax_name) {
+ $new_name = 'de ' . $item[$ax_key];
+ } elseif ($ax_name2 == "d'" . $ax_name) {
+ $new_name = "d'" . $item[$ax_key];
+ } elseif ($ax_name2 == 'du ' . $ax_name) {
+ $new_name = 'du ' . $item[$ax_key];
+ }
+
+ if ($new_name) {
+ XDB::execute("UPDATE fusionax_anciens
+ SET $ax_key = {?}
+ WHERE ax_id = {?}",
+ $new_name, $item['ax_id']);
+ ++$count;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return $count;
+}
+
+function fix_xorg_particles($ax, $xorg, $item)
+{
+ $count = 0;
+ foreach ($ax as $ax_key => $ax_name) {
+ if (!in_array($ax_name, $xorg)) {
+ foreach ($xorg as $xorg_key => $xorg_name) {
+ $new_name = '';
+ if ($xorg_name && strpos($ax_name, $xorg_name) !== false) {
+ if ($ax_name == 'de ' . $xorg_name) {
+ $new_name = 'de ' . $item[$xorg_key];
+ } elseif ($ax_name == "d'" . $xorg_name) {
+ $new_name = "d'" . $item[$xorg_key];
+ } elseif ($ax_name == 'du ' . $xorg_name) {
+ $new_name = 'du ' . $item[$xorg_key];
+ }
+
+ if ($new_name) {
+ XDB::execute("UPDATE profile_public_names
+ SET $xorg_key = {?}
+ WHERE pid = {?}",
+ $new_name, $item['pid']);
+ ++$count;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return $count;
+}
+
+function fix_xorg_full_name($ax, $xorg, $item)
+{
+ $new_name = '';
+ if (!in_array($ax['Nom_complet'], $xorg) && strpos($ax['Nom_complet'], $xorg['lastname_main']) !== false && $xorg['lastname_ordinary'] == '') {
+ XDB::execute("UPDATE profile_public_names
+ SET lastname_main = {?}, lastname_ordinary = {?}
+ WHERE pid = {?}",
+ $item['Nom_complet'], $item['lastname_main'], $item['pid']);
+ return 1;
+ }
+
+ return 0;
+}
+
+function fix_xorg_ordinary_name($ax, $xorg, $item)
+{
+ $new_name = '';
+ if (!in_array($ax['Nom_usuel'], $xorg) && $xorg['lastname_ordinary'] == '') {
+ XDB::execute("UPDATE profile_public_names
+ SET lastname_ordinary = {?}
+ WHERE pid = {?}",
+ $item['Nom_usuel'], $item['pid']);
+ return 1;
+ }
+
+ return 0;
+}
+
+function format($string)
+{
+ $string = preg_replace('/\-/', ' ', $string);
+ return preg_replace('/\s+/', ' ', $string);
+}
+
+$updates_count = 0;
+$count = 0;
+$total = count($res);
+foreach($res as $item) {
+ array_map('trim', $item);
+ $ax = array(
+ 'Nom_patronymique' => format(mb_strtolower(replace_accent($item['Nom_patronymique']))),
+ 'Nom_usuel' => format(mb_strtolower(replace_accent($item['Nom_usuel']))),
+ 'Nom_complet' => format(mb_strtolower(replace_accent($item['Nom_complet'])))
+ );
+ $xorg = array(
+ 'lastname_initial' => format(mb_strtolower(replace_accent($item['lastname_initial']))),
+ 'lastname_main' => format(mb_strtolower(replace_accent($item['lastname_main']))),
+ 'lastname_ordinary' => format(mb_strtolower(replace_accent($item['lastname_ordinary'])))
+ );
+
+ $updates_count += fix_ax_particles($ax, $xorg, $item);
+ $updates_count += fix_xorg_particles($ax, $xorg, $item);
+ $updates_count += fix_xorg_full_name($ax, $xorg, $item);
+ $updates_count += fix_xorg_ordinary_name($ax, $xorg, $item);
+ printf("\r%u / %u", $count, $total);
+ ++$count;
+}
+printf("\r%u / %u\n\n", $count, $total);
+
+echo "Nombre de mises à jour effectuées : " . $updates_count . ".\n";
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
--- /dev/null
+ALTER TABLE profile_public_names DROP COLUMN particles;
+ALTER TABLE accounts ADD COLUMN sort_name VARCHAR(255) DEFAULT NULL AFTER directory_name;
+
+-- vim:set syntax=mysql:
--- /dev/null
+ALTER TABLE requests_answers MODIFY COLUMN category ENUM('alias','liste','usage','photo','evts','gapps-unsuspend','marketing','orange','homonyme','nl','paiements','medal','broken','surveys', 'entreprise','account','address','bulkaccounts') NOT NULL DEFAULT 'alias';
+
+-- vim:set syntax=mysql:
--- /dev/null
+UPDATE profiles SET ax_id = '20110202' WHERE pid = 47038;
+
+-- vim:set syntax=mysql:
--- /dev/null
+../../bin/connect.db.inc.php
\ No newline at end of file
--- /dev/null
+#!/usr/bin/php5
+<?php
+require_once 'connect.db.inc.php';
+require_once '../../include/name.func.inc.php';
+
+// Returns the lower-cased name; if proper capitalization rule was not known,
+// warns the user, and returns the initial name.
+function capitalize_name_checked($name)
+{
+ if ($name == '') {
+ return '';
+ }
+
+ $capitalized = capitalize_name($name);
+ if (!$capitalized) {
+ echo " - WARNING: Unable to capitalize '$name'.\n";
+ return $name;
+ }
+ if (mb_strtolower($name, 'UTF-8') != mb_strtolower($capitalized, 'UTF-8')) {
+ echo " - WARNING: Capitalization of '$name' is unexpected: '$capitalized'\n";
+ return $name;
+ }
+
+ return $capitalized;
+}
+
+// Returns true iff the @p name looks like it should be properly recapitalized.
+function needs_conversion($name)
+{
+ if (strlen($name) == 0) {
+ return false;
+ }
+ if ($name == mb_strtoupper($name, 'UTF-8')) {
+ return true;
+ }
+
+ $name_length = mb_strlen($name, 'UTF-8');
+ $name_capitals = preg_replace('/\P{Lu}/u', '', $name);
+ return (mb_strlen($name_capitals, 'UTF-8') > 0.4 * $name_length);
+}
+
+// Retrieves all the names to convert.
+$conversions = 0;
+$names = XDB::iterator('SELECT pid, lastname_initial, lastname_main, lastname_marital, lastname_ordinary,
+ firstname_initial, firstname_main, firstname_ordinary, pseudonym
+ FROM profile_public_names');
+$name_list = array('lastname_initial', 'lastname_main', 'lastname_marital', 'lastname_ordinary',
+ 'firstname_initial', 'firstname_main', 'firstname_ordinary', 'pseudonym');
+$total = $names->total();
+while ($item = $names->next()) {
+ foreach ($name_list as $type) {
+ $item[$type] = capitalize_name_checked($item[$type]);
+ }
+
+ XDB::execute('UPDATE profile_public_names
+ SET lastname_initial = {?}, lastname_main = {?}, lastname_marital = {?}, lastname_ordinary = {?},
+ firstname_initial = {?}, firstname_main = {?}, firstname_ordinary = {?}, pseudonym = {?}
+ WHERE pid = {?}',
+ $item['lastname_initial'], $item['lastname_main'], $item['lastname_marital'], $item['lastname_ordinary'],
+ $item['firstname_initial'], $item['firstname_main'], $item['firstname_ordinary'], $item['pseudonym'],
+ $item['pid']);
+ $profile = Profile::get($item['pid']);
+ update_display_names($profile, $item);
+
+ printf("\r%u / %u", $conversions, $total);
+ $conversions++;
+ unset($item, $profile);
+}
+
+printf("\r%u / %u", $conversions, $total);
+echo "\n$conversions names from profiles properly recapitalized.\n";
+
+$conversions = 0;
+$names = XDB::iterator('SELECT uid, firstname, lastname
+ FROM accounts
+ WHERE NOT EXISTS (SELECT 1
+ FROM account_profiles
+ WHERE account_profiles.uid = accounts.uid)');
+
+$total = $names->total();
+while ($item = $names->next()) {
+ $lastname = capitalize_name_checked($item['lastname']);
+ $firstname = capitalize_name_checked($item['firstname']);
+
+ $full_name = build_full_name($firstname, $lastname);
+ $directory_name = build_directory_name($firstname, $lastname);
+ $sort_name = build_sort_name($firstname, $lastname);
+
+ XDB::execute('UPDATE accounts
+ SET firstname = {?}, lastname = {?}, full_name = {?}, directory_name = {?}, sort_name = {?}
+ WHERE uid = {?}',
+ $firstname, $lastname, $full_name, $directory_name, $sort_name, $item['uid']);
+
+ printf("\r%u / %u", $conversions, $total);
+ $conversions++;
+ unset($item);
+}
+printf("\r%u / %u", $conversions, $total);
+
+echo "\n$conversions names from accounts properly recapitalized.\n";
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
--- /dev/null
+#!/bin/bash
+
+. ../inc/pervasive.sh
+
+###########################################################
+[ "$DATABASE" != "x4dat" ] || die "Cannot target x4dat"
+
+confirm "* Running database upgrade scripts"
+mysql_run_directory .
--- /dev/null
+<?php
+/***************************************************************************
+ * 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 *
+ ***************************************************************************/
+
+require_once dirname(__FILE__) . '/../include/test.inc.php';
+
+class NameTest extends PlTestCase
+{
+ private static function checkPlatal()
+ {
+ global $platal;
+
+ if (is_null($platal)) {
+ $platal = new Xorg();
+ }
+ }
+
+ public static function nameProvider()
+ {
+ return array(
+ array('jacob', 'Jacob', 'Jacob'),
+ array('pierre-alexis', 'Pierre-Alexis', 'Pierre-Alexis'),
+ array('de gaulle', 'de Gaulle', 'Gaulle'),
+ array("d'abcdef", "d'Abcdef", "Abcdef"),
+ array("o'brian", "O'Brian", "O'Brian"),
+ array("malloc'h", "Malloc'h", "Malloc'h"),
+ array("D'IRUMBERRY DE SALABERRY", "d'Irumberry de Salaberry", "Irumberry de Salaberry"),
+ array("LE BOUCHER D'HEROUVILLE", "Le Boucher d'Herouville", "Le Boucher d'Herouville"),
+ array("ÖZTÜRK-N'Dong-Nzue", "Öztürk-N'Dong-Nzue", "Öztürk-N'Dong-Nzue"),
+ array('MAC NAMARA', 'Mac Namara', 'MacNamara'),
+ array('MACNAMARA', 'Macnamara', 'Macnamara'),
+ array('MCNAMARA', 'Mcnamara', 'Macnamara')
+ );
+ }
+
+ /**
+ * @dataProvider nameProvider
+ */
+ public function testName($name, $capitalized_name, $sort_name)
+ {
+ self::checkPlatal();
+ require_once 'name.func.inc.php';
+
+ $test = capitalize_name($name);
+ $this->assertEquals($test, $capitalized_name);
+ $this->assertEquals(build_sort_name('', $test), $sort_name);
+ }
+}
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>