# Developers: list 'public' tables here.
SHARED_TABLES="account_types \
forums \
- geoloc_administrativeareas \
geoloc_countries \
- geoloc_localities \
- geoloc_subadministrativeareas \
+ geoloc_languages \
log_actions \
newsletter_cat \
profile_binet_enum \
profile_langskill_enum \
profile_medal_enum \
profile_medal_grade_enum \
-profile_name_enum \
profile_networking_enum \
profile_section_enum \
profile_skill_enum \
* Each of these consts contains the basename of the class (its full name
* being DE_$basename).
*/
- const NAMETYPES = 'nametypes';
- const NAMES = 'names';
-
const BINETS = 'binets';
const GROUPESX = 'groupesx';
const SECTIONS = 'sections';
const ORIGINCORPS = 'origincorps';
const CORPSRANKS = 'corpsranks';
- const NATIONALITIES = 'nationalities';
- const COUNTRIES = 'countries';
- const ADMINAREAS = 'adminareas';
- const SUBADMINAREAS = 'subadminareas';
- const LOCALITIES = 'localities';
+ const NATIONALITIES = 'nationalities';
+ const SUBLOCALITIES = 'sublocalities';
+ const LOCALITIES = 'localities';
+ const ADMNISTRATIVEAREAS3 = 'admnistrativeareas3';
+ const ADMNISTRATIVEAREAS2 = 'admnistrativeareas2';
+ const ADMNISTRATIVEAREAS1 = 'admnistrativeareas1';
+ const COUNTRIES = 'countries';
const COMPANIES = 'companies';
const JOBDESCRIPTION = 'jobdescription';
}
// }}}
-// {{{ class DE_NameTypes
-// returns 'system' names ('lastname', 'lastname_marital', ...)
-class DE_NameTypes extends DirEnumeration
-{
- public $capabilities = 0x005; // self::HAS_OPTIONS | self::SAVE_IN_SESSION;
-
- protected $from = 'profile_name_enum';
- protected $valfield = 'type';
-}
-// }}}
-
-// {{{ class DE_Names
-// returns 'system' names ('lastname', 'lastname_marital', ...)
-class DE_Names extends DirEnumeration
-{
- public $capabilities = 0x005; // self::HAS_OPTIONS | self::SAVE_IN_SESSION;
-
- protected $from = 'profile_name_enum';
- protected $idfield = 'type';
- protected $valfield = 'name';
-}
-// }}}
-
/** GROUPS
*/
// {{{ class DE_Binets
}
// }}}
- // {{{ class DE_Countries
- class DE_Countries extends DirEnumeration
+ // {{{ class DE_AddressesComponents
+ class DE_AddressesComponents extends DirEnumeration
{
- protected $idfield = 'geoloc_countries.iso_3166_1_a2';
- protected $valfield = 'geoloc_countries.country';
- protected $valfield2 = 'geoloc_countries.countryEn';
- protected $from = 'geoloc_countries';
+ protected $idfield = 'profile_addresses_components_enum.id';
+ protected $valfield = 'profile_addresses_components_enum.long_name';
+ protected $from = 'profile_addresses_components_enum';
- protected $ac_join = 'INNER JOIN profile_addresses ON (geoloc_countries.iso_3166_1_a2 = profile_addresses.countryId)';
- protected $ac_unique = 'profile_addresses.pid';
- protected $ac_where = 'profile_addresses.type = \'home\'';
+ protected $ac_join = 'INNER JOIN profile_addresses_components ON (profile_addresses_components.component_id = profile_addresses_components_enum.id)';
+ protected $ac_unique = 'profile_addresses_components.pid';
}
// }}}
-
- // {{{ class DE_AdminAreas
- class DE_AdminAreas extends DE_WithSuboption
+ // {{{ class DE_AddressesComponents extensions
+ class DE_Countries extends DE_AddressesComponents
{
- protected $idfield = 'geoloc_administrativeareas.id';
- protected $optfield = 'geoloc_administrativeareas.country';
- protected $valfield = 'geoloc_administrativeareas.name';
- protected $from = 'geoloc_administrativeareas';
+ protected $where = 'WHERE FIND_IN_SET(\'country\', profile_addresses_components_enum.types)';
+ protected $ac_where = 'profile_addresses_components.type = \'home\' AND FIND_IN_SET(\'country\', profile_addresses_components_enum.types)';
+ }
- protected $ac_join = 'INNER JOIN profile_addresses ON (profile_addresses.administrativeAreaId = geoloc_administrativeareas.id)';
- protected $ac_unique = 'profile_addresses.pid';
+ class DE_Admnistrativeareas1 extends DE_AddressesComponents
+ {
+ protected $where = 'WHERE FIND_IN_SET(\'admnistrative_area_1\', profile_addresses_components_enum.types)';
+ protected $ac_where = 'profile_addresses_components.type = \'home\' AND FIND_IN_SET(\'admnistrative_area_1\', profile_addresses_components_enum.types)';
}
- // }}}
- // {{{ class DE_SubAdminAreas
- class DE_SubAdminAreas extends DE_WithSuboption
+ class DE_Admnistrativeareas2 extends DE_AddressesComponents
{
- protected $idfield = 'geoloc_subadministrativeareas.id';
- protected $optfield = 'geoloc_subadministrativeareas.administrativearea';
- protected $valfield = 'geoloc_subadministrativeareas.name';
- protected $from = 'geoloc_subadministrativeareas';
+ protected $where = 'WHERE FIND_IN_SET(\'admnistrative_area_2\', profile_addresses_components_enum.types)';
+ protected $ac_where = 'profile_addresses_components.type = \'home\' AND FIND_IN_SET(\'admnistrative_area_2\', profile_addresses_components_enum.types)';
+ }
- protected $ac_join = 'INNER JOIN profile_addresses ON (profile_addresses.subadministrativeAreaId = geoloc_subadministrativeareas.id)';
- protected $ac_unique = 'profile_addresses.pid';
+ class DE_Admnistrativeareas3 extends DE_AddressesComponents
+ {
+ protected $where = 'WHERE FIND_IN_SET(\'admnistrative_area_3\', profile_addresses_components_enum.types)';
+ protected $ac_where = 'profile_addresses_components.type = \'home\' AND FIND_IN_SET(\'admnistrative_area_3\', profile_addresses_components_enum.types)';
}
- // }}}
- // {{{ class DE_Localities
- class DE_Localities extends DirEnumeration
+ class DE_Localities extends DE_AddressesComponents
{
- protected $idfield = 'geoloc_localities.id';
- protected $valfield = 'geoloc_localities.name';
- protected $from = 'geoloc_localities';
+ protected $where = 'WHERE FIND_IN_SET(\'locality\', profile_addresses_components_enum.types)';
+ protected $ac_where = 'profile_addresses_components.type = \'home\' AND FIND_IN_SET(\'locality\', profile_addresses_components_enum.types)';
+ }
- protected $ac_join = 'INNER JOIN profile_addresses ON (profile_addresses.localityID = geoloc_localities.id)';
- protected $ac_unique = 'profile_addresses.pid';
+ class DE_Sublocalities extends DE_AddressesComponents
+ {
+ protected $where = 'WHERE FIND_IN_SET(\'sublocality\', profile_addresses_components_enum.types)';
+ protected $ac_where = 'profile_addresses_components.type = \'home\' AND FIND_IN_SET(\'sublocality\', profile_addresses_components_enum.types)';
}
+
// }}}
/** JOBS
}
}
+ public static function educationDuration($education)
+ {
+ switch ($education) {
+ case self::DEGREE_X:
+ return 3;
+ case self::DEGREE_M:
+ return 2;
+ case self::DEGREE_D:
+ return 3;
+ default:
+ return 0;
+ }
+ }
+
/** Number of years between the promotion year until the
* graduation year. In standard schools it's 0, but for
* Polytechnique the promo year is the entry year.
return 0;
}
+ // Returns the profile's color.
+ public function promoColor()
+ {
+ switch ($this->mainEducation()) {
+ case 'X':
+ if (($this->yearpromo() % 2) === 0) {
+ return 'red';
+ } else {
+ return 'yellow';
+ }
+ case 'M':
+ return 'green';
+ case 'D':
+ return 'blue';
+ default:
+ return 'gray';
+ }
+ }
+
/** Print a name with the given formatting:
* %s = • for women
* %f = firstname
public function nationalities()
{
$nats = array();
- $countries = DirEnum::getOptions(DirEnum::COUNTRIES);
+ $nationalities = DirEnum::getOptions(DirEnum::NATIONALITIES);
if ($this->nationality1) {
- $nats[$this->nationality1] = $countries[$this->nationality1];
+ $nats[$this->nationality1] = $nationalities[$this->nationality1];
}
if ($this->nationality2) {
- $nats[$this->nationality2] = $countries[$this->nationality2];
+ $nats[$this->nationality2] = $nationalities[$this->nationality2];
}
if ($this->nationality3) {
- $nats[$this->nationality3] = $countries[$this->nationality3];
+ $nats[$this->nationality3] = $nationalities[$this->nationality3];
}
return $nats;
}
* profile_job, profile_langskills, profile_mentor, profile_networking,
* profile_phones, profile_skills, watch_profile
* *always keeps in: profile_corps, profile_display, profile_education,
- * profile_medals, profile_name, profile_photos, search_name
+ * profile_medals, profile_*_names, profile_photos, search_name
* *modifies: profiles
*/
public function clear()
IF (p.freetext_pub IN {?}, p.freetext, NULL) AS freetext,
pe.entry_year, pe.grad_year, pe.promo_year, pe.program, pe.fieldid,
IF ({?}, pse.text, NULL) AS section,
- pn_f.name AS firstname, pn_l.name AS lastname,
- IF ({?}, pn_n.name, NULL) AS nickname,
- IF (pn_uf.name IS NULL, pn_f.name, pn_uf.name) AS firstname_ordinary,
- IF (pn_ul.name IS NULL, pn_l.name, pn_ul.name) AS lastname_ordinary,
+ ppn.firstname_main AS firstname, ppn.lastname_main AS lastname, IF ({?}, pn.name, NULL) AS nickname,
+ IF (ppn.firstname_ordinary = \'\', ppn.firstname_main, ppn.firstname_ordinary) AS firstname_ordinary,
+ IF (ppn.lastname_ordinary = \'\', ppn.firstname_main, ppn.lastname_ordinary) AS lastname_ordinary,
pd.yourself, pd.promo, pd.short_name, pd.public_name AS full_name,
pd.directory_name, pd.public_name, pd.private_name,
IF (pp.pub IN {?}, pp.display_tel, NULL) AS mobile,
INNER JOIN profile_display AS pd ON (pd.pid = p.pid)
INNER JOIN profile_education AS pe ON (pe.pid = p.pid AND FIND_IN_SET(\'primary\', pe.flags))
LEFT JOIN profile_section_enum AS pse ON (pse.id = p.section)
- INNER JOIN profile_name AS pn_f ON (pn_f.pid = p.pid
- AND pn_f.typeid = ' . self::getNameTypeId('firstname', true) . ')
- INNER JOIN profile_name AS pn_l ON (pn_l.pid = p.pid
- AND pn_l.typeid = ' . self::getNameTypeId('lastname', true) . ')
- LEFT JOIN profile_name AS pn_uf ON (pn_uf.pid = p.pid
- AND pn_uf.typeid = ' . self::getNameTypeId('firstname_ordinary', true) . ')
- LEFT JOIN profile_name AS pn_ul ON (pn_ul.pid = p.pid
- AND pn_ul.typeid = ' . self::getNameTypeId('lastname_ordinary', true) . ')
- LEFT JOIN profile_name AS pn_n ON (pn_n.pid = p.pid
- AND pn_n.typeid = ' . self::getNameTypeId('nickname', true) . ')
+ INNER JOIN profile_public_names AS ppn ON (ppn.pid = p.pid)
+ LEFT JOIN profile_private_names AS pn ON (pn.pid = p.pid AND type = \'nickname\')
LEFT JOIN profile_phones AS pp ON (pp.pid = p.pid AND pp.link_type = \'user\' AND tel_type = \'mobile\')
LEFT JOIN profile_photos AS ph ON (ph.pid = p.pid)
LEFT JOIN profile_mentor AS pm ON (pm.pid = p.pid)
}
}
- public static function getNameTypeId($type, $for_sql = false)
- {
- if (!S::has('name_types')) {
- $table = XDB::fetchAllAssoc('type', 'SELECT id, type
- FROM profile_name_enum');
- S::set('name_types', $table);
- } else {
- $table = S::v('name_types');
- }
- if ($for_sql) {
- return XDB::escape($table[$type]);
- } else {
- return $table[$type];
- }
- }
-
public static function rebuildSearchTokens($pids, $transaction = true)
{
+ require_once 'name.func.inc.php';
if (!is_array($pids)) {
$pids = array($pids);
}
- $keys = XDB::iterator("(SELECT n.pid AS pid, n.name AS name, e.score AS score, e.general_type,
- IF(FIND_IN_SET('public', e.flags), 'public', '') AS public
- FROM profile_name AS n
- INNER JOIN profile_name_enum AS e ON (n.typeid = e.id)
- WHERE n.pid IN {?} AND NOT FIND_IN_SET('not_displayed', e.flags))
- UNION
- (SELECT n.pid AS pid, n.particle AS name, 0 AS score, e.general_type,
- IF(FIND_IN_SET('public', e.flags), 'public', '') AS public
- FROM profile_name AS n
- INNER JOIN profile_name_enum AS e ON (n.typeid = e.id)
- WHERE n.pid IN {?} AND NOT FIND_IN_SET('not_displayed', e.flags))
- ",
- $pids, $pids);
+ $keys = XDB::iterator("(SELECT pid, name, type, IF(type = 'nickname', 2, 1) AS score, '' AS public
+ FROM profile_private_names
+ WHERE pid IN {?})
+ UNION
+ (SELECT pid, lastname_main, 'lastname' AS type, 10 AS score, 'public' AS public
+ FROM profile_public_names
+ WHERE lastname_main != '' AND pid IN {?})
+ UNION
+ (SELECT pid, lastname_marital, 'lastname' AS type, 10 AS score, 'public' AS public
+ FROM profile_public_names
+ WHERE lastname_marital != '' AND pid IN {?})
+ UNION
+ (SELECT pid, lastname_ordinary, 'lastname' AS type, 10 AS score, 'public' AS public
+ FROM profile_public_names
+ WHERE lastname_ordinary != '' AND pid IN {?})
+ UNION
+ (SELECT pid, firstname_main, 'firstname' AS type, 10 AS score, 'public' AS public
+ FROM profile_public_names
+ WHERE firstname_main != '' AND pid IN {?})
+ UNION
+ (SELECT pid, firstname_ordinary, 'firstname' AS type, 10 AS score, 'public' AS public
+ FROM profile_public_names
+ WHERE firstname_ordinary != '' AND pid IN {?})
+ UNION
+ (SELECT pid, pseudonym, 'nickname' AS type, 10 AS score, 'public' AS public
+ FROM profile_public_names
+ WHERE pseudonym != '' AND pid IN {?})",
+ $pids, $pids, $pids, $pids, $pids, $pids, $pids);
$names = array();
while ($key = $keys->next()) {
if ($key['name'] == '') {
continue;
}
- $pid = $key['pid'];
- require_once 'name.func.inc.php';
+ $pid = $key['pid'];
$toks = split_name_for_search($key['name']);
$toks = array_reverse($toks);
$token = $tok . $token;
$names["$pid-$token"] = XDB::format('({?}, {?}, {?}, {?}, {?}, {?})',
$token, $pid, soundex_fr($token),
- $eltScore, $key['public'], $key['general_type']);
+ $eltScore, $key['public'], $key['type']);
}
}
if ($transaction) {
static public function sortByName()
{
- return array(new UFO_Name(Profile::LASTNAME), new UFO_Name(Profile::FIRSTNAME));
+ return array(new UFO_Name());
}
static public function sortByPromo()
{
- return array(new UFO_Promo(), new UFO_Name(Profile::LASTNAME), new UFO_Name(Profile::FIRSTNAME));
+ return array(new UFO_Promo(), new UFO_Name());
}
static private function getDBSuffix($string)
return $joins;
}
- /** NAMES
- */
-
- static public function assertName($name)
- {
- if (!DirEnum::getID(DirEnum::NAMETYPES, $name)) {
- Platal::page()->kill('Invalid name type: ' . $name);
- }
- }
-
- private $pn = array();
- public function addNameFilter($type, $variant = null)
- {
- $this->requireProfiles();
- if (!is_null($variant)) {
- $ft = $type . '_' . $variant;
- } else {
- $ft = $type;
- }
- $sub = '_' . $ft;
- self::assertName($ft);
-
- if (!is_null($variant) && $variant == 'other') {
- $sub .= $this->option++;
- }
- $this->pn[$sub] = DirEnum::getID(DirEnum::NAMETYPES, $ft);
- return $sub;
- }
-
- protected function nameJoins()
- {
- $joins = array();
- foreach ($this->pn as $sub => $type) {
- $joins['pn' . $sub] = PlSqlJoin::left('profile_name', '$ME.pid = $PID AND $ME.typeid = {?}', $type);
- }
- return $joins;
- }
-
/** NAMETOKENS
*/
private $name_tokens = array();
/** ADDRESSES
*/
- private $with_pa = false;
- public function addAddressFilter()
+ private $types = array();
+ public function addAddressFilter($type)
{
$this->requireProfiles();
$this->with_pa = true;
- return 'pa';
- }
-
- private $with_pac = false;
- public function addAddressCountryFilter()
- {
- $this->requireProfiles();
- $this->addAddressFilter();
- $this->with_pac = true;
- return 'gc';
- }
- private $with_pal = false;
- public function addAddressLocalityFilter()
- {
- $this->requireProfiles();
- $this->addAddressFilter();
- $this->with_pal = true;
- return 'gl';
+ $sub = '_' . $this->option++;
+ $this->types[$type] = $sub;
+ return $sub;
}
protected function addressJoins()
{
$joins = array();
- if ($this->with_pa) {
- $joins['pa'] = PlSqlJoin::left('profile_addresses', '$ME.pid = $PID');
- }
- if ($this->with_pac) {
- $joins['gc'] = PlSqlJoin::left('geoloc_countries', '$ME.iso_3166_1_a2 = pa.countryID');
- }
- if ($this->with_pal) {
- $joins['gl'] = PlSqlJoin::left('geoloc_localities', '$ME.id = pa.localityID');
+ foreach ($this->types as $type => $sub) {
+ $joins['pa' . $sub] = PlSqlJoin::inner('profile_addresses', '$ME.pid = $PID');
+ $joins['pac' . $sub] = PlSqlJoin::inner('profile_addresses_components',
+ '$ME.pid = pa' . $sub . '.pid AND $ME.jobid = pa' . $sub . '.jobid AND $ME.groupid = pa' . $sub . '.groupid AND $ME.type = pa' . $sub . '.type AND $ME.id = pa' . $sub . '.id');
+ $joins['pace' . $sub] = PlSqlJoin::inner('profile_addresses_components_enum',
+ '$ME.id = pac' . $sub . '.component_id AND FIND_IN_SET({?}, $ME.types)', $type);
}
+
return $joins;
}
}
}
// }}}
-// {{{ class UFC_Name
-/** Filters users based on name
- * @param $type Type of name field on which filtering is done (firstname, lastname...)
- * @param $text Text on which to filter
- * @param $mode Flag indicating search type (prefix, suffix, with particule...)
+// {{{ class UFC_NameInitial
+/** Filters users based on sort_name
+ * @param $initial Initial on which to filter
*/
-class UFC_Name extends UserFilterCondition
+class UFC_NameInitial extends UserFilterCondition
{
- const EXACT = XDB::WILDCARD_EXACT; // 0x000
- const PREFIX = XDB::WILDCARD_PREFIX; // 0x001
- const SUFFIX = XDB::WILDCARD_SUFFIX; // 0x002
- const CONTAINS = XDB::WILDCARD_CONTAINS; // 0x003
- const PARTICLE = 0x004;
- const VARIANTS = 0x008;
+ private $initial;
- private $type;
- private $text;
- private $mode;
-
- public function __construct($type, $text, $mode)
- {
- $this->type = $type;
- $this->text = $text;
- $this->mode = $mode;
- }
-
- private function buildNameQuery($type, $variant, $where, UserFilter $uf)
+ public function __construct($initial)
{
- $sub = $uf->addNameFilter($type, $variant);
- return str_replace('$ME', 'pn' . $sub, $where);
+ $this->initial = $initial;
}
public function buildCondition(PlFilter $uf)
{
- $left = '$ME.name';
- if (($this->mode & self::PARTICLE) == self::PARTICLE) {
- $left = 'CONCAT($ME.particle, \' \', $ME.name)';
- }
- $right = XDB::formatWildcards($this->mode & self::CONTAINS, $this->text);
-
- $cond = $left . $right;
- $conds = array($this->buildNameQuery($this->type, null, $cond, $uf));
- if (($this->mode & self::VARIANTS) != 0 && isset(Profile::$name_variants[$this->type])) {
- foreach (Profile::$name_variants[$this->type] as $var) {
- $conds[] = $this->buildNameQuery($this->type, $var, $cond, $uf);
- }
- }
- return implode(' OR ', $conds);
+ $sub = $uf->addDisplayFilter();
+ return 'SUBSTRING(pd.sort_name, 1, 1) ' . XDB::formatWildcards(XDB::WILDCARD_PREFIX, $this->initial);
}
public function export()
{
- $export = $this->buildExport($this->type);
- if ($this->mode & self::VARIANTS) {
- $export['search_in_variants'] = true;
- }
- if ($this->mode & self::PARTICLE) {
- $export['search_in_particle'] = true;
- }
- $export['comparison'] = self::comparisonFromXDBWildcard($this->mode & 0x3);
- $export['text'] = $this->text;
+ $export = $this->buildExport($this->initial);
return $export;
}
}
// {{{ class UFC_Address
abstract class UFC_Address extends UserFilterCondition
{
- /** Valid address type ('hq' is reserved for company addresses)
+ /** Valid address type
*/
- const TYPE_HOME = 1;
- const TYPE_PRO = 2;
- const TYPE_ANY = 3;
+ const TYPE_HOME = 1;
+ const TYPE_PRO = 2;
+ const TYPE_NON_HQ = 3;
+ const TYPE_HQ = 4;
+ const TYPE_ANY = 7;
/** Text for these types
*/
protected static $typetexts = array(
self::TYPE_HOME => 'home',
self::TYPE_PRO => 'pro',
+ self::TYPE_HQ => 'hq',
);
protected $type;
}
}
if (count($types)) {
- $conds[] = XDB::format($sub . '.type IN {?}', $types);
+ $conds[] = XDB::format('pa' . $sub . '.type IN {?}', $types);
}
if ($this->flags != self::FLAG_ANY) {
foreach(self::$flagtexts as $flag => $text) {
if ($flag & $this->flags) {
- $conds[] = 'FIND_IN_SET(' . XDB::format('{?}', $text) . ', ' . $sub . '.flags)';
+ $conds[] = 'FIND_IN_SET(' . XDB::format('{?}', $text) . ', pa' . $sub . '.flags)';
}
}
}
}
// }}}
- // {{{ class UFC_AddressText
- /** Select users based on their address, using full text search
- * @param $text Text for filter in fulltext search
- * @param $textSearchMode Mode for search (one of XDB::WILDCARD_*)
- * @param $type Filter on address type
- * @param $flags Filter on address flags
- * @param $country Filter on address country
- * @param $locality Filter on address locality
- */
- class UFC_AddressText extends UFC_Address
- {
-
- private $text;
- private $textSearchMode;
-
- public function __construct($text = null, $textSearchMode = XDB::WILDCARD_CONTAINS,
- $type = null, $flags = self::FLAG_ANY, $country = null, $locality = null)
- {
- parent::__construct($type, $flags);
- $this->text = $text;
- $this->textSearchMode = $textSearchMode;
- $this->country = $country;
- $this->locality = $locality;
- }
-
- private function mkMatch($txt)
- {
- return XDB::formatWildcards($this->textSearchMode, $txt);
- }
-
- public function buildCondition(PlFilter $uf)
- {
- $sub = $uf->addAddressFilter();
- $conds = $this->initConds($sub, $uf->getVisibilityCondition($sub . '.pub'));
- if ($this->text != null) {
- $conds[] = $sub . '.text' . $this->mkMatch($this->text);
- }
-
- if ($this->country != null) {
- $subc = $uf->addAddressCountryFilter();
- $subconds = array();
- $subconds[] = $subc . '.country' . $this->mkMatch($this->country);
- $subconds[] = $subc . '.countryFR' . $this->mkMatch($this->country);
- $conds[] = implode(' OR ', $subconds);
- }
-
- if ($this->locality != null) {
- $subl = $uf->addAddressLocalityFilter();
- $conds[] = $subl . '.name' . $this->mkMatch($this->locality);
- }
-
- return implode(' AND ', $conds);
- }
- }
- // }}}
// {{{ class UFC_AddressField
/** Filters users based on their address,
* @param $val Either a code for one of the fields, or an array of such codes
* @param $type Filter on address type
* @param $flags Filter on address flags
*/
- class UFC_AddressField extends UFC_Address
+ class UFC_AddressComponent extends UFC_Address
{
- const FIELD_COUNTRY = 1;
- const FIELD_ADMAREA = 2;
- const FIELD_SUBADMAREA = 3;
- const FIELD_LOCALITY = 4;
- const FIELD_ZIPCODE = 5;
+ static $components = array('sublocality', 'locality', 'administrative_area_level_3', 'administrative_area_level_2', 'administrative_area_level_1', 'country');
/** Data of the filter
*/
private $val;
private $fieldtype;
+ private $exact;
- public function __construct($val, $fieldtype, $type = null, $flags = self::FLAG_ANY)
+ public function __construct($val, $fieldtype, $exact = true, $type = null, $flags = self::FLAG_ANY)
{
- parent::__construct($type, $flags);
+ if (!in_array($fieldtype, self::$components)) {
+ Platal::page()->killError('Invalid address field type: ' . $this->fieldtype);
+ }
+ parent::__construct($type, $flags);
if (!is_array($val)) {
$val = array($val);
}
$this->val = $val;
$this->fieldtype = $fieldtype;
+ $this->exact = $exact;
}
public function buildCondition(PlFilter $uf)
{
- $sub = $uf->addAddressFilter();
- $conds = $this->initConds($sub, $uf->getVisibilityCondition($sub . '.pub'));
-
- switch ($this->fieldtype) {
- case self::FIELD_COUNTRY:
- $field = 'countryId';
- break;
- case self::FIELD_ADMAREA:
- $field = 'administrativeAreaId';
- break;
- case self::FIELD_SUBADMAREA:
- $field = 'subAdministrativeAreaId';
- break;
- case self::FIELD_LOCALITY:
- $field = 'localityId';
- break;
- case self::FIELD_ZIPCODE:
- $field = 'postalCode';
- break;
- default:
- Platal::page()->killError('Invalid address field type: ' . $this->fieldtype);
- }
- $conds[] = XDB::format($sub . '.' . $field . ' IN {?}', $this->val);
+ $sub = $uf->addAddressFilter($this->fieldtype);
+ $conds = $this->initConds($sub, $uf->getVisibilityCondition('pa' . $sub . '.pub'));
+ $conds[] = XDB::format('pace' . $sub . '.id IN {?}', $this->val);
return implode(' AND ', $conds);
}
while ($('#search_name_' + i).length != 0) {
i++;
}
- $('#search_name_' + i)
- .updateHtml('profile/ajax/searchname/' + i + '/' + isFemale,
- function(data) {
- $('#searchname').before(data);
- changeNameFlag(i);
- });
+ $('#search_name_' + i).updateHtml('profile/ajax/searchname/' + i + '/' + isFemale,
+ function(data) {
+ $('#searchname').before(data);
+ });
}
function removeSearchName(i, isFemale)
updateNameDisplay(isFemale);
}
-function changeNameFlag(i)
-{
- $('#flag_' + i).remove();
- var typeid = $('#search_name_' + i).find('select').val();
- var type = $('#search_name_' + i).find('select :selected').text();
- if ($('[name=sn_type_' + typeid + '_' + i + ']').val() > 0) {
- $('#flag_cb_' + i).after('<span id="flag_' + i + '"> ' +
- '<img src="images/icons/flag_green.gif" alt="site public" title="site public" />' +
- '<input type="hidden" name="search_names[' + i + '][pub]" value="1"/>' +
- '<input type="hidden" name="search_names[' + i + '][typeid]" value="' + typeid + '"/>' +
- '<input type="hidden" name="search_names[' + i + '][type]" value="' + type + '"/></span>');
- } else {
- $('#flag_cb_' + i).after('<span id="flag_' + i + '"> ' +
- '<img src="images/icons/flag_red.gif" alt="site privé" title="site privé" />' +
- '<input type="hidden" name="search_names[' + i + '][typeid]" value="' + typeid + '"/>' +
- '<input type="hidden" name="search_names[' + i + '][type]" value="' + type + '"/></span>');
- }
-}
-
function updateNameDisplay(isFemale)
{
+ var lastnames = new Array('lastname_main', 'lastname_ordinary', 'lastname_marital', 'pseudonym');
+ var firstnames = new Array('firstname_main', 'firstname_ordinary');
var searchnames = '';
- for (var i = 0; i < 10; i++) {
+
+ for (var i = 0; i < 4; ++i) {
+ searchnames += $('.names_advanced').find('[name*=' + lastnames[i] + ']').val() + ';';
+ }
+ searchnames += '-;'
+ for (var i = 0; i < 2; ++i) {
+ searchnames += $('.names_advanced').find('[name*=' + firstnames[i] + ']').val() + ';';
+ }
+ searchnames += '-';
+
+ var has_private = false;
+ for (var i = 0; i < 10; ++i) {
if ($('#search_name_' + i).find(':text').val()) {
- searchnames += $('#search_name_' + i).find('[name*=typeid]').val() + ';';
- searchnames += $('#search_name_' + i).find(':text').val() + ';;';
+ searchnames += ';' + $('#search_name_' + i).find('[name*=type]').val() + ';' + $('#search_name_' + i).find(':text').val();
+ has_private = true;
}
}
+ searchnames += (has_private ? '' : ';');
$.xget('profile/ajax/buildnames/' + searchnames + '/' + isFemale,
function(data){
var name = data.split(';');
});
}
-function toggleParticle(id)
-{
- if ($('#search_name_' + id).find("[name*='[particle]']").val() == '') {
- $('#search_name_' + id).find("[name*='[particle]']").val(1);
- } else {
- $('#search_name_' + id).find("[name*='[particle]']").val('');
- }
-}
-
// Promotions {{{1
function togglePromotionEdition()
}
}
- function addAddress()
+ function addAddress(pid)
{
var i = 0;
while ($('#addresses_' + i + '_cont').length != 0) {
i++;
}
$('#add_address').before('<div id="addresses_' + i + '_cont"></div>');
- $('#addresses_' + i + '_cont').updateHtml('profile/ajax/address/' + i,
+ $('#addresses_' + i + '_cont').updateHtml('profile/ajax/address/' + i + '/' + pid,
checkCurrentAddress());
}
- function addressChanged(prefid)
+ function addressChanged(prefid, color)
{
+ var text = $('#' + prefid + '_cont').find("[name*='[text]']").val();
$('#' + prefid + '_cont').find('[name*=changed]').val("1");
+ $.xpost('map_url/', { text:text, color:color }, function(data) {
+ $('#' + prefid + '_static_map_url').show();
+ $('#' + prefid + '_static_map_url').find('img').attr('src', data);
+ });
}
- function validGeoloc(prefid, id, geoloc)
+ function deleteGeocoding(prefid)
{
- if (geoloc == 1) {
- $('#' + prefid + '_cont').find('[name*=text]').val($('#' + prefid + '_cont').find('[name*=geocodedText]').val());
- $('#' + prefid + '_cont').find('[name*=postalText]').val('');
- }
- if (geoloc > 0) {
- $('#' + prefid + '_cont').find("[name*='[geocodedText]']").remove();
+ if($('#' + prefid + '_geocoding_removal').find('[name*=request]:checkbox:checked').length == 0) {
+ return true;
}
- $('#' + prefid + '_cont').find('[name*=text]').removeClass('error');
- $('#' + prefid + '_cont').find('[name*=geocodeChosen]').val(geoloc);
- $('.' + prefid + '_geoloc').remove();
+
+ return confirm(
+ "La localisation de l'adresse sert à deux choses : te placer dans "
+ + "le planisphère et te faire apparaître dans la recherche avancée par "
+ + "pays, région, département, ville... La supprimer t'en fera disparaître. "
+ + "\nIl ne faut le faire que si cette localisation "
+ + "est réellement erronée. Avant de supprimer cette localisation, l'équipe de "
+ + "Polytechnique.org tentera de la réparer.\n\nConfirmes-tu ta "
+ + "demande de suppression de cette localisation ?");
}
// {{{1 Phones
&& $this->params['starts_with'] != null) {
$this->set->addCond(
- new UFC_Name(Profile::LASTNAME,
- $this->params['starts_with'], UFC_Name::PREFIX)
+ new UFC_NameInitial($this->params['starts_with'])
);
}
return parent::apply($page);
}
}
+ class MapView implements PlView
+ {
+ private $set;
+
+ public function __construct(PlSet $set, array $params)
+ {
+ $this->set = $set;
+ }
+
+ public function apply(PlPage $page)
+ {
+ Platal::load('geoloc');
+
+ if (Get::b('ajax')) {
+ $pids = $this->set->getIds(new PlLimit());
+ GeolocModule::assign_json_to_map($page, $pids);
+ $page->runJSON();
+ exit;
+ } else {
+ $this->set->getIds(new PlLimit());
+ GeolocModule::prepare_map($page);
+ return 'geoloc/index.tpl';
+ }
+ }
+
+ public function args()
+ {
+ return $this->set->args();
+ }
+ }
+
class GadgetView implements PlView
{
public function __construct(PlSet $set, array $params)
$params[1]);
$array = $res->next();
} else {
- $res = XDB::iterRow("SELECT p.birthdate, pa.text, pa.postalCode
- gl.name, pa.countryId, p.pid, pa.id
- FROM profiles AS p
- LEFT JOIN profile_addresses AS pa ON (pa.pid = p.pid)
- LEFT JOIN geoloc_localities AS gl ON (pl.id = pa.localityId)
+ $res = XDB::iterRow("SELECT p.birthdate, pa.text, GROUP_CONCAT(pace3.short_name), GROUP_CONCAT(pace2.short_name),
+ GROUP_CONCAT(pace1.short_name), p.pid, pa.id
+ FROM profiles AS p
+ LEFT JOIN profile_addresses AS pa ON (pa.pid = p.pid)
+ LEFT JOIN profile_addresses_components AS pc ON (pa.pid = pc.pid AND pa.jobid = pc.jobid AND pa.groupid = pc.groupid
+ AND pa.type = pc.type AND pa.id = pc.id)
+ LEFT JOIN profile_addresses_components_enum AS pace1 ON (FIND_IN_SET(\'country\', pace1.types) AND pace1.id = pc.component_id)
+ LEFT JOIN profile_addresses_components_enum AS pace2 ON (FIND_IN_SET(\'locality\', pace2.types) AND pace2.id = pc.component_id)
+ LEFT JOIN profile_addresses_components_enum AS pace3 ON (FIND_IN_SET(\'postal_code\', pace3.types) AND pace3.id = pc.component_id)
WHERE p.xorg_id = {?} AND NOT FIND_IN_SET('job', pa.flags)
ORDER BY NOT FIND_IN_SET('current', pa.flags),
FIND_IN_SET('secondary', pa.flags),
- NOT FIND_IN_SET('mail', pa.flags)",
+ NOT FIND_IN_SET('mail', pa.flags)
+ GROUP BY pa.pid, pa.jobid, pa.groupid, pa.id, pa.type",
$params[1]);
// Process the addresses we got.
if(list($age, $text, $adr['cp'], $adr['ville'],
}
// We check we actually have an identification number.
if(!empty($params[1])) {
- $nameTypes = DirEnum::getOptions(DirEnum::NAMETYPES);
- $nameTypes = array_flip($nameTypes);
-
- $res = XDB::query("SELECT pnl.name AS nom, pnu.name AS nom_usage, pnf.name AS prenom,
+ $res = XDB::query("SELECT ppn.lastname_initial AS nom, ppn.lastname_ordinary AS nom_usage, ppn.firstname_initial AS prenom,
p.sex = 'female' AS femme, p.deathdate IS NOT NULL AS decede,
p.birthdate, pd.promo, CONCAT(e.email, '@', d.name) AS mail
FROM profiles AS p
INNER JOIN email_source_account AS s ON (s.uid = ap.uid AND FIND_IN_SET('bestalias', s.flags))
INNER JOIN email_virtual_domains AS d ON (s.domain = s.id)
INNER JOIN profile_display AS pd PN (p.pid = pd.pid)
- INNER JOIN profile_name AS pnl ON (p.pid = pnl.pid AND pnl.typeid = {?})
- INNER JOIN profile_name AS pnf ON (p.pid = pnf.pid AND pnf.typeid = {?})
- INNER JOIN profile_name AS pnu ON (p.pid = pnu.pid AND pnu.typeid = {?})
+ INNER JOIN profile_public_names AS ppn ON (ppn.pid = p.pid)
WHERE a.flags = 'bestalias' AND p.xorg_id = {?}",
- $nameTypes['name_ini'], $nameTypes['lastname_ordinary'],
- $nameTypes['firstname_ini'], $params[1]);
+ $params[1]);
// $data['mail'] .= '@polytechnique.org';
'profile/ax' => $this->make_hook('ax', AUTH_COOKIE, 'admin,edit_directory'),
'profile/edit' => $this->make_hook('p_edit', AUTH_MDP),
'profile/ajax/address' => $this->make_hook('ajax_address', AUTH_COOKIE, 'user', NO_AUTH),
+ 'profile/ajax/address/del' => $this->make_hook('ajax_address_del', AUTH_MDP),
'profile/ajax/tel' => $this->make_hook('ajax_tel', AUTH_COOKIE, 'user', NO_AUTH),
'profile/ajax/edu' => $this->make_hook('ajax_edu', AUTH_COOKIE, 'user', NO_AUTH),
'profile/ajax/medal' => $this->make_hook('ajax_medal', AUTH_COOKIE, 'user', NO_AUTH),
'javascript/education.js' => $this->make_hook('education_js', AUTH_COOKIE),
'javascript/grades.js' => $this->make_hook('grades_js', AUTH_COOKIE),
'profile/medal' => $this->make_hook('medal', AUTH_PUBLIC),
- 'profile/name_info' => $this->make_hook('name_info', AUTH_PUBLIC),
'referent' => $this->make_hook('referent', AUTH_COOKIE),
'referent/country' => $this->make_hook('ref_country', AUTH_COOKIE, 'user', NO_AUTH),
'admin/trombino' => $this->make_hook('admin_trombino', AUTH_MDP, 'admin'),
'admin/corps_enum' => $this->make_hook('admin_corps_enum', AUTH_MDP, 'admin'),
'admin/corps_rank' => $this->make_hook('admin_corps_rank', AUTH_MDP, 'admin'),
- 'admin/names' => $this->make_hook('admin_names', AUTH_MDP, 'admin'),
);
}
exit;
}
- function handler_name_info($page)
- {
- pl_content_headers("text/html");
- $page->changeTpl('profile/name_info.tpl', SIMPLE);
- $res = XDB::iterator("SELECT name, explanations,
- FIND_IN_SET('public', flags) AS public,
- FIND_IN_SET('has_particle', flags) AS has_particle
- FROM profile_name_enum
- WHERE NOT FIND_IN_SET('not_displayed', flags)
- ORDER BY NOT FIND_IN_SET('public', flags)");
- $page->assign('types', $res);
- }
-
function handler_networking($page, $mid)
{
$res = XDB::query("SELECT icon
}
$page->setTitle('Mon Profil');
+ $page->assign('hrpid', $profile->hrid());
if (isset($success) && $success) {
$page->trigSuccess('Ton profil a bien été mis à jour.');
}
$page->assign('medal_list', $mlist);
}
- function handler_ajax_address($page, $id)
+ function handler_ajax_address($page, $id, $pid)
{
pl_content_headers("text/html");
$page->changeTpl('profile/adresses.address.tpl', NO_SKIN);
$page->assign('i', $id);
$page->assign('address', array());
+ $page->assign('profile', Profile::get($pid));
+ $page->assign('isMe', true);
+ $page->assign('geocoding_removal', true);
}
function handler_ajax_tel($page, $prefid, $prefname, $telid, $subField, $mainField, $mainId)
function handler_ajax_searchname($page, $id, $isFemale)
{
pl_content_headers("text/html");
- $page->changeTpl('profile/general.searchname.tpl', NO_SKIN);
- $res = XDB::query("SELECT id, name, FIND_IN_SET('public', flags) AS pub
- FROM profile_name_enum
- WHERE NOT FIND_IN_SET('not_displayed', flags)
- AND NOT FIND_IN_SET('always_displayed', flags)");
- $page->assign('sn_type_list', $res->fetchAllAssoc());
+ $page->changeTpl('profile/general.private_name.tpl', NO_SKIN);
+ $page->assign('other_names', array('nickname' => 'Surnom', 'firstname' => 'Autre prénom', 'lastname' => 'Autre nom'));
+ $page->assign('new_name', true);
$page->assign('isFemale', $isFemale);
- $page->assign('i', $id);
+ $page->assign('id', $id);
}
function handler_ajax_buildnames($page, $data, $isFemale)
break;
}
}
- function handler_admin_names($page, $action = 'list', $id = null) {
- $page->setTitle('Administration - Types de noms');
- $page->assign('title', 'Gestion des types de noms');
- $table_editor = new PLTableEditor('admin/names', 'profile_name_enum', 'id', true);
- $table_editor->describe('name', 'Nom', true);
- $table_editor->describe('explanations', 'Explications', true);
- $table_editor->describe('type', 'Type', true);
- $table_editor->describe('flags', 'Flags', true);
- $table_editor->describe('score', 'Score', true);
- $table_editor->apply($page, $action, $id);
- }
function handler_admin_binets($page, $action = 'list', $id = null) {
$page->setTitle('Administration - Binets');
$page->assign('title', 'Gestion des binets');
+Check that the following queries return the same results before updating:
+SELECT COUNT(*), COUNT(DISTINCT(pid)) FROM profile_name AS pn INNER JOIN profile_name_enum AS pne ON (pn.typeid = pne.id) WHERE pne.type = 'nickname';
+SELECT COUNT(*), COUNT(DISTINCT(pid)) FROM profile_name AS pn INNER JOIN profile_name_enum AS pne ON (pn.typeid = pne.id) WHERE pne.type = 'name_other';
+SELECT COUNT(*), COUNT(DISTINCT(pid)) FROM profile_name AS pn INNER JOIN profile_name_enum AS pne ON (pn.typeid = pne.id) WHERE pne.type = 'firstname_other';
++
+ Once all sql/php scripts have be run, run retrieve_address_tables.sh and finally xx_retrieve_geocoding.sql.
+ Then "./formatAddresses.php -g -t g -r e" will format the last ungeocoded addresses.
+
+ Additions to platal.conf:
+ [Maps]
+ api_version = "3.4" (depending on current version when releasing)
+ language = "fr"