Pierre Habouzit <pierre.habouzit@m4x.org>, <madcoder@debian.org>
Aymeric Augustin <aymeric.augustin@m4x.org>
Jean Sébastien Bedo <jean-sebastien.bedo@m4x.org>
+ Raphaël Barrois <raphael.barrois@m4x.org>
Florent Bruneau <florent.bruneau@m4x.org>
Sophie Charbonnier <sophie.charbonnier@m4x.org>
Yann Chevalier <yann.chevalier@m4x.org>
Jean-Marc Coic <jean-marc.coic@m4x.org>
Pascal Corpet <pascal.corpet@m4x.org>
Guillaume Gommard <guillaume.gommard@m4x.org>
+ Stéphane Jacob <stephane.jacob@m4x.org>
Fabien Laborde <fabien.laborde@m4x.org>
Jeremy Lainé <jeremy.laine@m4x.org>
Olivier Le Floch <olivier.le-floch@m4x.org>
Raphael Marichez <raphael.marichez@m4x.org>
Vincent Palatin <vincent.palatin@m4x.org>
+ Vincent Zanotti <vincent.zanotti@m4x.org>
XML-RPC stuff :
================================================================================
VERSION 0.10.1 XX XX XXXX
+New:
+
+ * Events:
+ - Reminders -JAC/VZA
+
+Bug/Wish:
+
+ * Admin:
+ - #965: Prevents password hashes from being broadcasted by email -VZA
+
+ * AXLetter:
+ - Enables axletter mailings to a subset of subscribers -XEL
+
+ * Core:
+ - #680: Retrieve dead redirections thanks to inactive redirections -JAC
+
+ * Mail:
+ - Notifies the sender when a moderated message to a ML is accepted -JAC
+ - #963: Fixes notification email on removal of "nom d'usage" -VZA
+ - #972: Adds a legend on the email redirection page -JAC
+
+ * Payment:
+ - #669: Sends comments with the payment notifications -JAC
+
+ * Profile:
+ - #951: The address of a dead person is her last address -JAC
+ - #958: Fix the address in the professionnal vcard -JAC
+ - #970: Shows a confirmation message when the profile is modified -JAC
+
+ * Marketing:
+ - #671: Displays more statistics about marketings -JAC
+
+ * Survey:
+ - #794: Adds wiki syntax to surveys -PIK
+
+ * XnetGrp:
+ - #973: Only site administrators can allow AX aggregation -JAC
+
From 0.10.0 branch:
* Auth:
* THD: Thomas Deniau (Totom) <thomas.deniau@m4x.org>
* VP : Vincent Palatin <vincent.palatin@m4x.org>
* XdX: Alexandre Hô (XandreX) <alexandre.ho@m4x.org>
+ * XEL: Raphaël Barrois (Xelnor) <raphael.barrois@m4x.org>
* VZA: Vincent Zanotti (vinZ2) <vincent.zanotti@m4x.org>
================================================================================
openid: get-openid spool/openid/store
# There is no obvious way to automatically use the latest version
+OPENID_VERSION = 2.1.3
get-openid:
@if ! test -d include/Auth; then \
- wget http://openidenabled.com/files/php-openid/packages/php-openid-2.1.2.tar.bz2; \
- tar -xjf php-openid-2.1.2.tar.bz2; \
- mv php-openid-2.1.2/Auth include/; \
- rm php-openid-2.1.2.tar.bz2; \
- rm -r php-openid-2.1.2; \
+ wget http://openidenabled.com/files/php-openid/packages/php-openid-$(OPENID_VERSION).tar.bz2; \
+ tar -xjf php-openid-$(OPENID_VERSION).tar.bz2; \
+ mv php-openid-$(OPENID_VERSION)/Auth include/; \
+ rm php-openid-$(OPENID_VERSION).tar.bz2; \
+ rm -r php-openid-$(OPENID_VERSION); \
fi
spool/openid/store:
mkdir -p $@
chmod o+w $@
-
##
## banana
##
--- /dev/null
+# List of security fixes that have been committed to the "master" branch.
+# This list is used to programmatically determine if a checkout of plat/al has
+# known vulnerabilities (which is useful for automatically disabling an unused
+# and unsafe checkout).
+#
+# In order to guarantee that only patched checkouts do have an updated SECURITY
+# file, updates of this file should be done within the same sommit that actually
+# fixes the security issue. Since the commit id is not known yet, it can be
+# replaced by '00000000', and updated later.
+#
+# Format: <date> <commit id> <commit description>
+# The commit id should refer to the id in the "master" branch, if the initial
+# commit in a version branch had another name.
+
+2009-10-19 e10bc2ef Prevents auth-groupex from leaking data to third-party attackers.
+2008-12-21 a25cdc91 Fixes a SQL injection in geoloc.inc.php.
--- /dev/null
+#!/usr/bin/env python
+#***************************************************************************
+#* Copyright (C) 2003-2009 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 *
+#***************************************************************************/
+
+"""Checks that a working copy of plat/al has all the latest security patches
+applied. It uses the local SECURITY file to determine the list of mandatory
+patches.
+
+Important notice: do not execute this script directly from an automatic checkout
+of plat/al. It would be extremely unwise to execute it with root privileges from
+a place where everybody can change it !
+
+Usage (-w updates the local .htaccess to disable guilty working copies):
+ check_security_fixes.py [-w] -b REFERENCE_PLATAL PLATAL_TO_CHECK ...
+"""
+
+import optparse
+import os
+import re
+import sys
+import time
+
+
+class WorkingCopy(object):
+ """Helper class for analyzing the state of a working copy, and eventually
+ disabling it if an issue is found.
+
+ It disables the local checkout by updating its .htaccess file to deny all
+ requests with an explicit message which states how to fix the issue.
+ """
+
+ CORE_SECURITY_FILE = 'core/SECURITY'
+ MASTER_SECURITY_FILE = 'SECURITY'
+ SECURITY_FIX_RE = re.compile('^-[0-9]{4}')
+
+ HTACCESS_FILE = 'htdocs/.htaccess'
+ HTACCESS_TEMPLATE = 'Deny from all\nErrorDocument 403 "%s"\n'
+ HTACCESS_MTIME_DELTA = 86400 * 365 * 10
+ ERROR_MESSAGE_LINE = '<li>%s</li>\n'
+ ERROR_MESSAGE_TEMPLATE = """
+ Your local checkout of plat/al has been disabled for security reasons. It
+ appears that several critical flaws known in the plat/al codebase have not
+ been patched in your working copy. These flaws are listed below:
+ <ul>%s</ul>
+
+ Please have a look at the SECURITY and core/SECURITY files in any recent
+ plat/al checkout to get more details on which commits did fix those flaws.
+ <br/><br/>
+
+ <em>Note:</em> you can re-enable your working copy by typing
+ <code>make</code> in the root directory of your checkout (usually in
+ <code>~/dev/platal</code>).
+ """
+
+ def __init__(self, reference_path, checkout_path):
+ self.reference_path = reference_path
+ self.checkout_path = checkout_path
+
+ def GetPartialSecurityDiff(self, security_file):
+ """Diffs the reference and a local SECURITY file to find missing security
+ fixes. It filters out the diff result to extract the list of fixes."""
+
+ ref_file = os.path.join(self.reference_path, security_file)
+ wc_file = os.path.join(self.checkout_path, security_file)
+
+ diff = os.popen('diff -NBwu0 %s %s' % (ref_file, wc_file))
+ for line in diff.readlines():
+ if self.SECURITY_FIX_RE.match(line):
+ yield line[1:-1]
+
+ def GetSecurityDiff(self):
+ """Retrieves the missing security patches for various parts of plat/al."""
+
+ missing_fixes = []
+ missing_fixes.extend(self.GetPartialSecurityDiff(self.CORE_SECURITY_FILE))
+ missing_fixes.extend(self.GetPartialSecurityDiff(self.MASTER_SECURITY_FILE))
+ return missing_fixes
+
+ def GetErrorMessage(self, missing_fixes):
+ """Returns a the .htaccess HTML error message.
+
+ It builds an HTML message explaining why the working copy was disabled, how
+ to fix the underlying issues, and how to re-enable it."""
+
+ fixes_list = map(lambda item: self.ERROR_MESSAGE_LINE % item, missing_fixes)
+ return self.ERROR_MESSAGE_TEMPLATE % '\n'.join(fixes_list)
+
+ def Write403Htaccess(self, html_content):
+ """Updates the .htaccess to disable all requests, using |html_content| as
+ the error message. It also sets a modification time in the past to ensure
+ that any subsquent call to 'make' on the wc will actually overwrite the
+ .htaccess file."""
+
+ htaccess = os.path.join(self.checkout_path, self.HTACCESS_FILE)
+ ht_fd = open(htaccess, 'w')
+ ht_fd.write(self.HTACCESS_TEMPLATE % (html_content
+ .replace('\\', '\\\\')
+ .replace('"', '\\"')
+ .replace('\n', '\\\n')))
+ ht_fd.close()
+
+ mtime = time.time() - self.HTACCESS_MTIME_DELTA
+ os.utime(htaccess, (mtime, mtime))
+
+ def CheckAndDisableWorkingCopy(self, disable_when_flawed):
+ """Checks that the local working copy is in a sane state. If not, warns the
+ user by printing a message to the console, and disables the wc if
+ |disable_when_flawed| is set to true."""
+
+ missing_fixes = self.GetSecurityDiff()
+ if len(missing_fixes):
+ # Warn the user on the standard output.
+ print "Found %d missing security fixes in %s:" % (len(missing_fixes),
+ self.checkout_path)
+ for issue in missing_fixes:
+ print " * %s" % issue
+
+ # Disable the working copy.
+ if disable_when_flawed:
+ print "Disabling working copy in %s." % self.checkout_path
+ self.Write403Htaccess(self.GetErrorMessage(missing_fixes))
+
+def SelfCheckIsLatestVersion(base_path):
+ """Checks that this script is the latest available by comparing itself to
+ the reference script in |base_path|. It is important to do that check as
+ most deployment will want to execute this script with root privileges,
+ which implies that this script is deployed in a safe directory, and not
+ just executed from an automatically updated checkout of plat/al (how
+ unsafe would that be ...)."""
+
+ base_script = os.path.join(base_path, 'bin/check_security_fixes.py')
+ local_script = os.path.abspath(sys.argv[0])
+
+ if os.system('diff -q %s %s' % (base_script, local_script)) != 0:
+ sys.stderr.write('Please upgrade this script to the latest version.\n')
+
+def main():
+ parser = optparse.OptionParser()
+ parser.add_option('-b', '--base_path', action='store', dest='base_path')
+ parser.add_option('-w', '--write_htaccess', action='store_true',
+ dest='write_htaccess', default=False)
+ (options, args) = parser.parse_args()
+
+ if options.base_path is None:
+ print "Error: option --base_path (or -b) is required for the script to run."
+ sys.exit(1)
+ if not os.path.exists(os.path.join(options.base_path,
+ WorkingCopy.MASTER_SECURITY_FILE)):
+ print "The base plat/al (%s) is too old to be used." % options.base_path
+ sys.exit(1)
+
+ SelfCheckIsLatestVersion(options.base_path)
+ for platal in args:
+ wc = WorkingCopy(options.base_path, platal)
+ wc.CheckAndDisableWorkingCopy(options.write_htaccess)
+
+if __name__ == '__main__':
+ main()
+
+# vim:set et sw=2 sts=2 sws=2 enc=utf-8:
// send feedback to the mailing list owners
if ($client->handle_request($list, $mid, $action, utf8_decode($reason))) {
$sent_mails += $count;
- $texte = "le message suivant :\n\n"
+ $texte = "Le message suivant :\n\n"
. " Auteur: {$mail['sender']}\n"
. " Sujet : « {$mail['subj']} »\n"
. " Date : ".strftime("le %d %b %Y à %H:%M:%S", (int)$mail['stamp'])."\n\n"
$age = (time() - intval($age)) / 86400;
$head = "";
if ($age > 15) {
- $head = "[autodestruction du serveur] ";
+ $head = "[Autodestruction du serveur] ";
} elseif ($age > 7) {
- $head = "[armageddon imminent] ";
+ $head = "[Armageddon imminent] ";
} elseif ($age > 5) {
- $head = "[guerre nucléaire] ";
+ $head = "[Guerre nucléaire] ";
} elseif ($age > 3) {
$head = "[ET Téléphone maison] ";
} elseif ($age > 1) {
- $head = "[réveil !] ";
+ $head = "[Réveil !] ";
} elseif (!empty($nbveryold)) {
- $head = "[urgent] ";
+ $head = "[Urgent] ";
}
$mymail = new PlMailer();
$mymail->setFrom('validation@' . $globals->mail->domain);
$mymail->addTo("validation@" . $globals->mail->domain);
-$mymail->setSubject($head . "il y a $nb validation$plural non effectuée$plural");
+$mymail->setSubject($head . "Il y a $nb validation$plural non effectuée$plural");
$message =
- "il y a $nb validation$plural à effectuer \n"
+ "Il y a $nb validation$plural à effectuer\n"
.(empty($nbold)?"":"dont $nbold depuis le dernier mail !!!\n")
.(empty($nbveryold)?"":"et dont *$nbveryold* ".($nbveryold == 1 ? "est" : "sont")." en retard de plus de 6h !!!")
."\n"
GROUP BY type
ORDER BY type");
while (list($type, $nb) = $res->next()) {
- $message .= "- $type: $nb\n";
+ $message .= "- $type : $nb\n";
}
$message = wordwrap($message,78);
$panne_level = 3;
require('./connect.db.inc.php');
+require("Console/Getopt.php");
+
+/*
+ * Parse the command-line options.
+ */
+$opts = Console_GetOpt::getopt($argv, 'v');
+$opt_verbose = false;
+
+if (PEAR::isError($opts)) {
+ echo $opts->getMessage();
+} else {
+ $opts = $opts[0];
+ foreach ($opts as $opt) {
+ if ($opt[0] == 'v') {
+ $opt_verbose = true;
+ }
+ }
+}
/*
* Check duplicated addresses
*/
-$sql = "SELECT a1.alias, a2.alias, e1.email
- FROM emails AS e1
- INNER JOIN emails AS e2 ON (e1.email = e2.email AND e1.uid != e2.uid
+$sql = "SELECT a1.alias, a2.alias, e1.email
+ FROM emails AS e1
+ INNER JOIN emails AS e2 ON (e1.email = e2.email AND e1.uid != e2.uid
AND (e1.uid < e2.uid OR NOT FIND_IN_SET('active', e2.flags)))
- LEFT JOIN emails_watch AS w ON (e1.email = w.email)
- INNER JOIN aliases AS a1 ON (a1.id = e1.uid AND a1.type = 'a_vie')
- INNER JOIN aliases AS a2 ON (a2.id = e2.uid AND a2.type = 'a_vie')
- INNER JOIN auth_user_md5 AS u1 ON (a1.id = u1.user_id)
- INNER JOIN auth_user_md5 AS u2 ON (a2.id = u2.user_id)
- WHERE FIND_IN_SET('active', e1.flags) AND u1.nom != u2.nom_usage AND u2.nom != u1.nom_usage AND w.email IS NULL
- ORDER BY a1.alias";
+ LEFT JOIN emails_watch AS w ON (e1.email = w.email)
+ INNER JOIN aliases AS a1 ON (a1.id = e1.uid AND a1.type = 'a_vie')
+ INNER JOIN aliases AS a2 ON (a2.id = e2.uid AND a2.type = 'a_vie')
+ INNER JOIN auth_user_md5 AS u1 ON (a1.id = u1.user_id)
+ INNER JOIN auth_user_md5 AS u2 ON (a2.id = u2.user_id)
+ WHERE FIND_IN_SET('active', e1.flags) AND u1.nom != u2.nom_usage AND u2.nom != u1.nom_usage AND w.email IS NULL
+ ORDER BY a1.alias";
$it = Xdb::iterRow($sql);
. "https://www.polytechnique.org/admin/emails/duplicated";
echo "\n\n";
- $sql = "INSERT IGNORE INTO emails_watch (email, state, detection, last)
- VALUES " . join(", ", $insert);
+ $sql = "INSERT IGNORE INTO emails_watch (email, state, detection, last)
+ VALUES " . join(", ", $insert);
XDB::execute($sql);
if (XDB::errno() != 0) {
echo 'Error : ' . XDB::error() . "\n$sql";
*/
if ($panne_level > 0) {
$sql = "SELECT e.email, u.hruid
- FROM emails AS e
+ FROM emails AS e
INNER JOIN auth_user_md5 AS u ON u.user_id = e.uid
WHERE e.panne_level = $panne_level AND e.flags = 'active'
ORDER BY u.hruid";
WHERE panne_level > $panne_level");
}
+/*
+ * Retrieve the users with no active redirection, but still one working
+ * inactive redirection.
+ */
+if ($opt_verbose) {
+ $res = XDB::query("SELECT u.hruid, ei.email
+ FROM auth_user_md5 AS u
+ LEFT JOIN emails AS ea ON (ea.uid = u.user_id AND ea.flags='active')
+ INNER JOIN emails AS ei ON (ei.uid = u.user_id AND ei.flags='')
+ WHERE FIND_IN_SET('googleapps', u.mail_storage) = 0 AND ea.email IS NULL
+ GROUP BY u.user_id");
+
+ if ($res->numRows()) {
+ $result = $res->fetchAllAssoc();
+ echo "Camarades n'ayant plus d'adresses actives, mais ayant une adresse inactive :\n";
+ foreach ($result as $user) {
+ echo '* ' . $user['email'] . ' pour ' . $user['hruid'] . "\n";
+ }
+ echo "\n";
+}
+
// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
?>
private $_profile_fetched = false;
private $_profile = null;
+ // Additional fields (non core)
+ protected $promo = null;
+
// Implementation of the login to uid method.
protected function getLogin($login)
{
public static function _default_user_callback($login, $results)
{
$result_count = count($results);
- if ($result_count == 0 || !S::has_perms()) {
+ if ($result_count == 0 || !S::admin()) {
Platal::page()->trigError("Il n'y a pas d'utilisateur avec l'identifiant : $login");
} else {
Platal::page()->trigError("Il y a $result_count utilisateurs avec cet identifiant : " . join(', ', $results));
$sub['créer une liste'] = "$dim/lists/create";
$sub['créer un alias'] = "$dim/alias/create";
}
- if (S::has_perms()) {
+ if (S::admin()) {
$sub['gérer les groupes'] = array('href' => 'admin', 'style' => 'color: gray;');
$sub['clear cache'] = array('href' => 'purge_cache?token=' . S::v('xsrf_token'), 'style' => 'color: gray;');
}
$menu['Administrer'] = $sub;
- } elseif (S::has_perms()) {
+ } elseif (S::admin()) {
$sub = array();
$sub['gérer les groupes'] = 'admin';
$sub['clear cache'] = 'purge_cache?token=' . S::v('xsrf_token');
LEFT JOIN gapps_accounts AS g ON(a.uid = g.l_userid AND g.g_status = 'active')
LEFT JOIN logger.last_sessions AS ls ON (ls.uid = a.uid)
LEFT JOIN logger.sessions AS s ON(s.id = ls.id)
- WHERE a.uid = {?} AND a.state = 'active'", $user->id());
+ WHERE a.uid = {?} AND u.perms IN('admin', 'user')", $user->id());
+ if ($res->numRows() != 1) {
+ return false;
+ }
+
$sess = $res->fetchOneAssoc();
$perms = $sess['perms'];
unset($sess['perms']);
return true;
}
- /** Start a session without authentication data for the given user.
- * This is used to identify the user after his registration, to be
- * removed after rewriting registration procedure.
- * XXX: Temporary
- */
- public function startWeakSession($user)
- {
- if (!$this->startSessionAs($user, AUTH_MDP)) {
- $this->destroy();
- return false;
- }
- S::set('auth', AUTH_MDP);
- return true;
- }
-
private function securityChecks()
{
$mail_subject = array();
# db
0 5 * * * web cd $WD; ./clean.php
-0 21 * * 1-6 web cd $WD; ./checkdb.php | mail -e -s "verifications sur la BDD de plat/al @VERSION@" br@staff.m4x.org
-0 21 * * 0 web cd $WD; ./checkdb.php -v | mail -e -s "verifications verbose sur la BDD de plat/al @VERSION@" br@staff.m4x.org
-0 20 * * * web cd $WD; ./emails.check.php | mail -e -s "qualite de l'annuaire" br@staff.m4x.org
+0 21 * * 1-6 web cd $WD; ./checkdb.php | mail -e -s "Verifications sur la BDD de plat/al @VERSION@" br@staff.m4x.org
+0 21 * * 0 web cd $WD; ./checkdb.php -v | mail -e -s "Verifications verbeuses sur la BDD de plat/al @VERSION@" br@staff.m4x.org
+0 20 2-31 * * web cd $WD; ./emails.check.php | mail -e -s "Qualite de l'annuaire" br@staff.m4x.org
+0 20 1 * * web cd $WD; ./emails.check.php -v | mail -e -s "Qualite de l'annuaire : verbeux" br@staff.m4x.org
0 22 * * * web cd $WD; ./phones.check.php > /dev/null
# inscription report
0 6 * * 1 web cd $WD; ./rapports_inscription.php
# notifs
-0 2 * * * web cd $WD; ./notifs.birthday.php
+0 2 * * * web cd $WD; ./notifs.birthday.php
0 4 * * 6 web cd $WD; ./notifs.send.php
# validations
*/5 * * * * www-data cd $WD; ./banana.feedgen.php > /dev/null
# AX spammer
-15 * * * * web cd $WD; ./axletter.send.php | mail -e -s "envoi d'un mail de l'AX" br@staff.m4x.org
+15 * * * * web cd $WD; ./axletter.send.php | mail -e -s "Envoi d'un email de l'AX" br@staff.m4x.org
# homonymes
0 0 4 * * web cd $WD; ./homonymes.php
-Subproject commit e8ddc3f28701273de2b5c0f822146ab2a39dea91
+Subproject commit 6c36b907ae72344efb81730e3b41a0ddc9473cec
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
***************************************************************************/
-function readCookie(name)
-{
- var nameEQ = name + "=";
- var ca = document.cookie.split(';');
- for(var i=0;i < ca.length;i++)
- {
- var c = ca[i];
- while (c.charAt(0)==' ') c = c.substring(1,c.length);
- if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
- }
- return null;
-}
-
-
function doChallengeResponse() {
var new_pass = hash_encrypt(document.forms.login.password.value);
- var old_pass = MD5(document.forms.login.password.value);
- str = readCookie('ORGuid') + ":" +
+ str = document.forms.loginsub.username.value + ":" +
hash_encrypt(document.forms.login.password.value) + ":" +
document.forms.loginsub.challenge.value;
document.forms.loginsub.response.value = hash_encrypt(str);
- document.forms.loginsub.xorpass.value = hash_xor(new_pass, old_pass);
document.forms.loginsub.remember.value = document.forms.login.remember.checked;
document.forms.login.password.value = "";
document.forms.loginsub.submit();
}
+
// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
document.forms.changepass2.submit();
return true;
}
+
+function EncryptedResponseInNestedForm() {
+ $('[name=nouveau]').val($('[name=password]').val());
+ $('[name=nouveau2]').val($('[name=password2]').val());
+ EnCryptedResponse();
+}
+
// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
});
}
+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('');
+ }
+}
+
// Nationalities {{{1
function delNationality(i)
function addPhoneComment(id)
{
- $(id + '_comment').show();
- $(id + '_addComment').hide();
+ $('#' + id + '_comment').show();
+ $('#' + id + '_addComment').hide();
}
function removePhoneComment(id, pref)
{
- $(id + '_comment').hide();
- $(id + '_comment').find("[name='" + pref + "[comment]']").val('');
- $(id + '_addComment').show();
+ $('#' + id + '_comment').hide();
+ $('#' + id + '_comment').find("[name='" + pref + "[comment]']").val('');
+ $('#' + id + '_addComment').show();
}
// {{{1 Groups
url = document.URL;
fqdn = url.replace(/^https?:\/\/([^\/]*)\/.*$/,'$1');
light = (url.indexOf('display=light') > url.indexOf('?'));
+ resource_page = (url.indexOf('rss') > -1 || url.indexOf('ical') > -1);
$("a,link").each(
function(i) {
href = 'http://' + fqdn + '/' + href;
}
}
- if (this.nodeName.toLowerCase() == 'a') {
+ if (this.nodeName.toLowerCase() == 'a' && !resource_page) {
if (rss && href.indexOf('prefs/rss') < 0 && (href.indexOf('xml') > -1 || href.indexOf('hash'))) {
goodiesPopup(this, __goodies_rss);
} else if (ical) {
'lists', 'marketing', 'payment', 'platal',
'profile', 'register', 'search', 'stats', 'admin',
'newsletter', 'axletter', 'bandeau', 'survey',
- 'fusionax', 'gadgets', 'googleapps', 'poison', 'openid');
+ 'fusionax', 'gadgets', 'googleapps', 'poison',
+ 'openid', 'reminder');
if (!($path = Env::v('n')) || ($path{0} < 'A' || $path{0} > 'Z')) {
$platal->run();
function hook_checkcancel($_headers)
{
- return ($_headers['x-org-id'] == S::v('hruid') or S::has_perms());
+ return ($_headers['x-org-id'] == S::v('hruid') or S::admin());
}
class ForumsBanana extends Banana
array_push(Banana::$msgparse_headers, 'x-org-id', 'x-org-mail');
Banana::$nntp_host = 'news://web_' . $user->login()
. ":{$globals->banana->password}@{$globals->banana->server}:{$globals->banana->port}/";
- if (S::has_perms()) {
+ if (S::admin()) {
Banana::$msgshow_mimeparts[] = 'source';
}
Banana::$debug_nntp = ($globals->debug & DEBUG_BT);
global $globals;
$perms = S::v('perms');
$group = $globals->asso('nom');
- if (S::has_perms()) {
+ if (S::admin()) {
return "Administrateur de Polytechnique.org";
} else if ($group && $perms->hasFlag('groupadmin')) {
return "Animateur de $group";
{
}
- public function process()
+ public function success() { }
+
+ public function process(&$success)
{
return PlWizard::CURRENT_PAGE;
}
Banana::$debug_smarty = ($globals->debug & DEBUG_SMARTY);
Banana::$mbox_helper = $globals->banana->mbox_helper;
Banana::$feed_updateOnDemand = true;
- if (S::has_perms()) {
+ if (S::admin()) {
Banana::$msgshow_mimeparts[] = 'source';
}
array_push(Banana::$msgparse_headers, 'x-org-id', 'x-org-mail');
function hook_checkcancel($_headers)
{
- return ($_headers['x-org-id'] == S::v('hruid') or S::has_perms());
+ return ($_headers['x-org-id'] == S::v('hruid') or S::admin());
}
function hook_makeLink($params)
!preg_match("/@(polytechnique\.(org|edu)|melix\.(org|net)|m4x\.org)$/", $email);
}
+// function ids_from_mails() {{{1
+// Converts an array of emails to an array of email => uid
+function ids_from_mails(array $emails)
+{
+ global $globals;
+ $domain_mails = array();
+ $alias_mails = array();
+ $other_mails = array();
+
+ // Determine the type of the email adresses. It can eiher be a domain
+ // email (@polytechnique.org), an alias email (@melix.net) or any other
+ // email (potentially used as a redirection by one user)
+ foreach ($emails as $email) {
+ if (strpos($email, '@') === false) {
+ $user = $email;
+ $domain = $globals->mail->domain2;
+ } else {
+ list($user, $domain) = explode('@', $email);
+ }
+ if ($domain == $globals->mail->alias_dom || $domain == $globals->mail->alias_dom2) {
+ list($user) = explode('+', $user);
+ list($user) = explode('_', $user);
+ $alias_mails[$user] = $email;
+ } elseif ($domain == $globals->mail->domain || $domain == $globals->mail->domain2) {
+ list($user) = explode('+', $user);
+ list($user) = explode('_', $user);
+ $domain_mails[$user] = $email;
+ } else {
+ $other_mails[] = $email;
+ }
+ }
+ $uids = array();
+
+ // Look up user ids for addresses in domain
+ if (count($domain_mails)) {
+ $domain_users = array_map(array('XDB', 'escape'), array_keys($domain_mails));
+ $list = implode(',', $domain_users);
+ $res = XDB::query("SELECT alias, id
+ FROM aliases
+ WHERE alias IN ($list)");
+ foreach ($res->fetchAllRow() as $row) {
+ list ($alias, $id) = $row;
+ $uids[$domain_mails[$alias]] = $id;
+ }
+ }
+
+ // Look up user ids for addresses in our alias domain
+ if (count($alias_mails)) {
+ $alias_users = array();
+ foreach (array_keys($alias_mails) as $user) {
+ $alias_users[] = XDB::escape($user."@".$globals->mail->alias_dom);
+ }
+ $list = implode(',', $alias_users);
+ $res = XDB::query("SELECT v.alias, a.id
+ FROM virtual AS v
+ INNER JOIN virtual_redirect AS r USING(vid)
+ INNER JOIN aliases AS a ON (a.type = 'a_vie'
+ AND r.redirect = CONCAT(a.alias, '@{$globals->mail->domain2}'))
+ WHERE v.alias IN ($list)");
+ foreach ($res->fetchAllRow() as $row) {
+ list ($alias, $id) = $row;
+ $uids[$alias_mails[$alias]] = $id;
+ }
+ }
+
+ // Look up user ids for other addresses in the email redirection list
+ if (count($other_mails)) {
+ $other_users = array_map(array('XDB', 'escape'), $other_mails);
+ $list = implode(',', $other_users);
+ $res = XDB::query("SELECT email, uid
+ FROM emails
+ WHERE email IN ($list)");
+ foreach ($res->fetchAllRow() as $row) {
+ list ($email, $uid) = $row;
+ $uids[$other_mails[$email]] = $uid;
+ }
+ }
+
+ return $uids;
+}
+
// class Bogo {{{1
// The Bogo class represents a spam filtering level in plat/al architecture.
class Bogo
public function clean_errors()
{
- if (!S::has_perms()) {
+ if (!S::admin()) {
return false;
}
$this->panne = 0;
// IMAP storage is always visible to administrators, and is allowed for
// everyone when the service is marked as 'active'.
- if ($globals->mailstorage->imap_active || S::has_perms()) {
+ if ($globals->mailstorage->imap_active || S::admin()) {
$storages[] = 'imap';
}
{
XDB::execute("UPDATE emails
SET flags = 'disable'
- WHERE flags = 'active' AND uid = {?}", $this->user->id);
+ WHERE flags = 'active' AND uid = {?}", $this->user->id());
foreach ($this->emails as &$mail) {
if ($mail->active && $mail->has_disable()) {
$mail->disabled = true;
{
XDB::execute("UPDATE emails
SET flags = 'active'
- WHERE flags = 'disable' AND uid = {?}", $this->user->id);
+ WHERE flags = 'disable' AND uid = {?}", $this->user->id());
foreach ($this->emails as &$mail) {
if ($mail->disabled) {
$mail->active = true;
$address['text'] = $address['geoloc'];
$address['postalText'] = $address['geocodedPostalText'];
unset($address['geoloc'], $address['geocodedPostalText']);
+ } else {
+ $address['geoloc'] = str_replace("\n", "\r\n", $address['geoloc']);
+ $address['geocodedPostalText'] = str_replace("\n", "\r\n", $address['geocodedPostalText']);
}
+ $address['text'] = str_replace("\n", "\r\n", $address['text']);
+ $address['postalText'] = str_replace("\n", "\r\n", $address['postalText']);
}
// Returns the address formated for postal use.
public $r_last_webmail;
public $reporting_date;
+ // Nicknames (aliases) registered for that user, lazily loaded.
+ public $nicknames;
+
// Pending requests in the gappsd job queue (cf. top note).
public $pending_create;
public $pending_delete;
return $this->g_status == 'disabled';
}
+ // Loads and returns the list of nicknames for the user.
+ public function nicknames()
+ {
+ if ($this->nicknames == null) {
+ $res = XDB::query(
+ "SELECT g_nickname
+ FROM gapps_nicknames
+ WHERE g_account_name = {?}
+ ORDER BY g_nickname",
+ $this->g_account_name);
+ $this->nicknames = $res->fetchColumn();
+ }
+ return $this->nicknames;
+ }
+
// Changes the GoogleApps password.
public function set_password($password) {
$new_alias, S::i('uid'));
}
require_once('user.func.inc.php');
- user_reindex($uid);
+ user_reindex(S::i('uid'));
return $has_new;
}
--- /dev/null
+<?php
+/***************************************************************************
+ * Copyright (C) 2003-2009 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 *
+ ***************************************************************************/
+
+// Base class for a reminder; it offers the factory for creating valid reminders
+// tailored for a given user, as well as base methods for reminder impls.
+// Sub-classes should define at least the abstract methods, and the static
+// IsCandidate method (prototype: (User &$user)).
+//
+// Usage:
+// // Instantiates and returns a valid Reminder object for the user.
+// $reminder = Reminder::GetCandidateReminder($user);
+//
+// // Returns the named Reminder object.
+// $reminder = Reminder::GetByName($user, 'ax_letter');
+abstract class Reminder
+{
+ // Details about the reminder.
+ public $name;
+ protected $type_id;
+ protected $weight;
+ protected $remind_delay_yes;
+ protected $remind_delay_no;
+ protected $remind_delay_dismiss;
+
+ // Details about the user.
+ protected $user;
+ protected $current_status;
+ protected $last_ask;
+
+ // Constructs the Reminder object from a mandatory User instance, a list of
+ // key-value pairs from the `reminder_type` and `reminder` tables.
+ function __construct(User &$user, array $type)
+ {
+ $this->user = &$user;
+
+ $this->type_id = $type['type_id'];
+ $this->name = $type['name'];
+ $this->weight = $type['weight'];
+ $this->remind_delay_yes = $type['remind_delay_yes'];
+ $this->remind_delay_no = $type['remind_delay_no'];
+ $this->remind_delay_dismiss = $type['remind_delay_dismiss'];
+
+ if (isset($type['status'])) {
+ $this->current_status = $type['status'];
+ }
+ if (isset($type['remind_last'])) {
+ $this->last_ask = $type['remind_last'];
+ }
+ }
+
+ // Updates (or creates) the reminder line for the pair (|user|, |reminder_id|)
+ // using the |status| as status, and the |next_ask| as the delay between now
+ // and the next ask (if any).
+ private static function UpdateStatus($user_id, $type_id, $status, $next_ask)
+ {
+ XDB::execute('REPLACE INTO reminder
+ SET uid = {?}, type_id = {?}, status = {?},
+ remind_last = NOW(), remind_next = FROM_UNIXTIME({?})',
+ $user_id, $type_id, $status,
+ ($next_ask > 0 ? time() + $next_ask * 24 * 60 * 60 : null));
+ }
+
+ // Updates the status of the reminder for the current user.
+ protected function UpdateOnYes()
+ {
+ $this->UpdateStatus($this->user->id(), $this->type_id,
+ 'yes', $this->remind_delay_yes);
+ }
+ protected function UpdateOnNo()
+ {
+ $this->UpdateStatus($this->user->id(), $this->type_id,
+ 'no', $this->remind_delay_no);
+ }
+ protected function UpdateOnDismiss()
+ {
+ $this->UpdateStatus($this->user->id(), $this->type_id,
+ 'dismiss', $this->remind_delay_dismiss);
+ }
+
+ // Display and http handling helpers --------------------------------------
+
+ // Handles a hit on the reminder onebox (for links made using the GetBaseUrl
+ // method below).
+ abstract public function HandleAction($action);
+
+ // Displays a reduced version of the reminder and notifies that the action
+ // has been taken into account.
+ public function NotifiesAction(&$page)
+ {
+ header('Content-Type: text/html; charset=utf-8');
+ $page->changeTpl('reminder/notification.tpl', NO_SKIN);
+ $page->assign('previous_reminder', $this->title());
+ }
+
+ // Displays the reminder as a standalone html snippet. It should be used
+ // when the reminder is the only output of a page.
+ public function DisplayStandalone(&$page, $previous_reminder = null)
+ {
+ header('Content-Type: text/html; charset=utf-8');
+ $page->changeTpl('reminder/base.tpl', NO_SKIN);
+ $this->Prepare($page);
+ if ($previous_reminder) {
+ $page->assign('previous_reminder', $previous_reminder);
+ }
+ }
+
+ // Prepares the display by assigning template variables.
+ public function Prepare(&$page)
+ {
+ $page->assign_by_ref('reminder', $this);
+ }
+
+ // Returns the name of the inner template, or null if a simple text obtained
+ // from GetText should be printed.
+ public function template() { return null; }
+
+ // Returns the text to display in the onebox, or null if a
+ public function text() { return ''; }
+
+ // Returns the title of the onebox.
+ public function title() { return ''; }
+
+ // Should return true if this onebox needs to be considered as a warning and
+ // not just as a subscription offer.
+ public function warning() { return false; }
+
+ // Returns the base url for the reminder module.
+ public function baseurl()
+ {
+ return 'ajax/reminder/' . $this->name;
+ }
+
+ // Returns the url for the information page.
+ public function info() { return ''; }
+
+ // Static status update methods -------------------------------------------
+
+ // Marks the candidate reminder as having been accepted for user |user_id|.
+ // It is intended to be used when a reminder box has been bypassed, and when
+ // it should behave as if the user had clicked on 'yes'.
+ protected static function MarkCandidateAsAccepted($user_id, $candidate)
+ {
+ Reminder::UpdateStatus($user_id, $candidate['type_id'],
+ 'yes', $candidate['remind_delay_yes']);
+ }
+
+ // Static factories -------------------------------------------------------
+
+ // Returns a chosen class using the user data from |user|, and from the database.
+ public static function GetCandidateReminder(User &$user)
+ {
+ $res = XDB::query('SELECT rt.*, r.status, r.remind_last
+ FROM reminder_type AS rt
+ LEFT JOIN reminder AS r ON (rt.type_id = r.type_id AND r.uid = {?})
+ WHERE r.uid IS NULL OR r.remind_next < NOW()',
+ $user->id());
+ $candidates = $res->fetchAllAssoc();
+
+ $weight_map = create_function('$a', 'return $a["weight"];');
+ while (count($candidates) > 0) {
+ $position = rand(1, array_sum(array_map($weight_map, $candidates)));
+ foreach ($candidates as $key => $candidate) {
+ $position -= $candidate['weight'];
+ if ($position <= 0) {
+ $class = self::GetClassName($candidate['name']);
+ if ($class && call_user_func(array($class, 'IsCandidate'), $user, $candidate)) {
+ return new $class($user, $candidate);
+ }
+ unset($candidates[$key]);
+ }
+ }
+ }
+
+ return null;
+ }
+
+ // Returns an instantiation of the reminder class which name is |name|, using
+ // user data from |user|, and from the database.
+ public static function GetByName(User &$user, $name)
+ {
+ if (!($class = self::GetClassName($name))) {
+ return null;
+ }
+
+ $res = XDB::query('SELECT rt.*, r.status, r.remind_last
+ FROM reminder_type AS rt
+ LEFT JOIN reminder AS r ON (rt.type_id = r.type_id AND r.uid = {?})
+ WHERE rt.name = {?}',
+ $user->id(), $name);
+ if ($res->numRows() > 0) {
+ return new $class($user, $res->fetchOneAssoc());
+ }
+
+ return null;
+ }
+
+ // Computes the name of the class for reminder named |name|, and preloads
+ // the class.
+ private static function GetClassName($name)
+ {
+ include_once "reminder/$name.inc.php";
+ $class = 'Reminder' . str_replace(' ', '', ucwords(str_replace('_', ' ', $name)));
+ return (class_exists($class) ? $class : null);
+ }
+}
+
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
--- /dev/null
+<?php
+/***************************************************************************
+ * Copyright (C) 2003-2009 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 *
+ ***************************************************************************/
+
+class ReminderAxLetter extends Reminder
+{
+ public function HandleAction($action)
+ {
+ if ($action == 'yes') {
+ Platal::load('axletter', 'axletter.inc.php');
+ AXLetter::subscribe();
+ $this->UpdateOnYes();
+ }
+
+ if ($action == 'dismiss') {
+ $this->UpdateOnDismiss();
+ }
+
+ if ($action == 'no') {
+ $this->UpdateOnNo();
+ }
+ }
+
+ public function text()
+ {
+ return "La lettre de l'AX te permet de recevoir régulièrement les
+ informations importantes de l'AX.";
+ }
+ public function title()
+ {
+ return "Inscription à la lettre de l'AX";
+ }
+ public function info()
+ {
+ return 'Xorg/MailsAX';
+ }
+
+ public static function IsCandidate(User &$user, $candidate)
+ {
+ Platal::load('axletter', 'axletter.inc.php');
+ $isSubscribed = AXLetter::subscriptionState();
+ if ($isSubscribed) {
+ Reminder::MarkCandidateAsAccepted($user->id(), $candidate);
+ }
+ return !$isSubscribed;
+ }
+}
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
--- /dev/null
+<?php
+/***************************************************************************
+ * Copyright (C) 2003-2009 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 *
+ ***************************************************************************/
+
+class ReminderEmailBackup extends Reminder
+{
+ public function HandleAction($action)
+ {
+ if ($action == 'yes') {
+ require_once 'emails.inc.php';
+ $storage = new EmailStorage($this->user, 'imap');
+ $storage->activate();
+
+ $this->UpdateOnYes();
+ }
+
+ if ($action == 'dismiss') {
+ $this->UpdateOnDismiss();
+ }
+
+ if ($action == 'no') {
+ $this->UpdateOnNo();
+ }
+ }
+
+ public function text()
+ {
+ return "Tu peux bénéficier d'une sauvegarde des emails. Cela permet
+ d'avoir un accès de secours aux 30 derniers jours d'emails reçus
+ sur ton adresse Polytechnique.org.";
+ }
+ public function title()
+ {
+ return 'Sauvegarde de tes emails';
+ }
+ public function info()
+ {
+ return 'Xorg/IMAP';
+ }
+
+ public static function IsCandidate(User &$user, $candidate)
+ {
+ require_once 'emails.inc.php';
+ $storage = new EmailStorage($user, 'imap');
+ if ($storage->active) {
+ Reminder::MarkCandidateAsAccepted($user->id(), $candidate);
+ }
+ return !$storage->active;
+ }
+}
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
--- /dev/null
+<?php
+/***************************************************************************
+ * Copyright (C) 2003-2009 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 *
+ ***************************************************************************/
+
+class ReminderEmailWarning extends Reminder
+{
+ public function HandleAction($action)
+ {
+ if ($action == 'dismiss') {
+ $this->UpdateOnDismiss();
+ }
+ }
+
+ public function template()
+ {
+ return 'reminder/email_warning.tpl';
+ }
+ public function title()
+ {
+ return "Problème avec ta redirections d'emails";
+ }
+ public function warning()
+ {
+ return true;
+ }
+
+ public static function IsCandidate(User &$user, $candidate)
+ {
+ return count(S::v('mx_failures', array())) > 0;
+ }
+}
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
--- /dev/null
+<?php
+/***************************************************************************
+ * Copyright (C) 2003-2009 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 *
+ ***************************************************************************/
+
+class ReminderGapps extends Reminder
+{
+ public function HandleAction($action)
+ {
+ switch ($action) {
+ case 'yes':
+ $this->UpdateOnDismiss();
+ pl_redirect('googleapps');
+ break;
+
+ case 'dismiss':
+ $this->UpdateOnDismiss();
+ break;
+
+ case 'no':
+ $this->UpdateOnNo();
+ break;
+ }
+ }
+
+ public function template()
+ {
+ return 'reminder/gapps.tpl';
+ }
+ public function title()
+ {
+ return "Création d'un compte Google Apps";
+ }
+ public function info()
+ {
+ return 'Xorg/GoogleApps';
+ }
+
+ public static function IsCandidate(User &$user, $candidate)
+ {
+ require_once 'googleapps.inc.php';
+ $isSubscribed = GoogleAppsAccount::account_status($user->id());
+ if ($isSubscribed == 'disabled') {
+ $isSubscribed = false;
+ }
+ if ($isSubscribed) {
+ Reminder::MarkCandidateAsAccepted($user->id(), $candidate);
+ }
+ return !$isSubscribed;
+ }
+}
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
--- /dev/null
+<?php
+/***************************************************************************
+ * Copyright (C) 2003-2009 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 *
+ ***************************************************************************/
+
+class ReminderMl extends Reminder
+{
+ public function HandleAction($action)
+ {
+ switch ($action) {
+ case 'suscribe':
+ S::assert_xsrf_token();
+ $subs = array_keys(Post::v('sub_ml'));
+ $current_domain = null;
+
+ $res = XDB::iterRow("SELECT sub, domain
+ FROM register_subs
+ WHERE uid = {?} AND type = 'list'
+ ORDER BY domain",
+ S::i('uid'));
+ while (list($sub, $domain) = $res->next()) {
+ if (array_shift($subs) == "$sub@$domain") {
+ if ($domain != $current_domain) {
+ $current_domain = $domain;
+ }
+ $client = new MMList(S::v('uid'), S::v('password'), $domain);
+ $client->subscribe($sub);
+ }
+ }
+
+ $this->UpdateOnYes();
+ pl_redirect('lists');
+ break;
+
+ case 'dismiss':
+ $this->UpdateOnDismiss();
+ break;
+
+ case 'no':
+ $this->UpdateOnNo();
+ break;
+ }
+ }
+
+ public function Prepare(&$page)
+ {
+ parent::Prepare($page);
+
+ $res = XDB::iterRow("SELECT sub, domain
+ FROM register_subs
+ WHERE uid = {?} AND type = 'list'
+ ORDER BY domain",
+ S::i('uid'));
+ $current_domain = null;
+ $lists = array();
+ while (list($sub, $domain) = $res->next()) {
+ if ($current_domain != $domain) {
+ $current_domain = $domain;
+ $client = new MMList(S::v('uid'), S::v('password'), $domain);
+ }
+ list($details, ) = $client->get_members($sub);
+ $lists["$sub@$domain"] = $details;
+ }
+ $page->assign_by_ref('lists', $lists);
+ }
+
+ public function template()
+ {
+ return 'reminder/ml.tpl';
+ }
+ public function title()
+ {
+ return "Inscription aux listes de diffusion";
+ }
+
+ public static function IsCandidate(User &$user, $candidate)
+ {
+ $res = XDB::query("SELECT COUNT(*) AS lists
+ FROM register_subs
+ WHERE uid = {?} AND type = 'list'",
+ $user->id());
+
+ $mlCount = $res->fetchOneCell();
+ if (!$mlCount) {
+ Reminder::MarkCandidateAsAccepted($user->id(), $candidate);
+ }
+ return ($mlCount > 0);
+ }
+}
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
--- /dev/null
+<?php
+/***************************************************************************
+ * Copyright (C) 2003-2009 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 *
+ ***************************************************************************/
+
+class ReminderNl extends Reminder
+{
+ public function HandleAction($action)
+ {
+ if ($action == 'yes') {
+ require_once 'newsletter.inc.php';
+ NewsLetter::subscribe();
+ $this->UpdateOnYes();
+ }
+
+ if ($action == 'dismiss') {
+ $this->UpdateOnDismiss();
+ }
+
+ if ($action == 'no') {
+ $this->UpdateOnNo();
+ }
+ }
+
+ public function text()
+ {
+ return "La lettre mensuelle de Polytechnique.org te permet de recevoir
+ chaque mois des informations sur les activités et nouvelles de la
+ communauté des X.";
+ }
+ public function title()
+ {
+ return "Inscription à la lettre mensuelle";
+ }
+
+ public static function IsCandidate(User &$user, $candidate)
+ {
+ require_once 'newsletter.inc.php';
+ $isSubscribed = NewsLetter::subscriptionState();
+ if ($isSubscribed) {
+ Reminder::MarkCandidateAsAccepted($user->id(), $candidate);
+ }
+ return !$isSubscribed;
+ }
+}
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
--- /dev/null
+<?php
+/***************************************************************************
+ * Copyright (C) 2003-2009 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 *
+ ***************************************************************************/
+
+class ReminderNoRedirection extends Reminder
+{
+ public function HandleAction($action)
+ {
+ if ($action == 'dismiss') {
+ $this->UpdateOnDismiss();
+ }
+ }
+
+ public function template()
+ {
+ return 'reminder/no_redirection.tpl';
+ }
+ public function title()
+ {
+ return "Problème avec ta redirection d'emails";
+ }
+ public function warning()
+ {
+ return true;
+ }
+ public function info()
+ {
+ return 'Xorg/MesAdressesDeRedirection';
+ }
+
+ public static function IsCandidate(User &$user, $candidate)
+ {
+ return S::v('no_redirect');
+ }
+}
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
--- /dev/null
+<?php
+/***************************************************************************
+ * Copyright (C) 2003-2009 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 *
+ ***************************************************************************/
+
+class ReminderProfileUpdate extends Reminder
+{
+ public function HandleAction($action)
+ {
+ switch ($action) {
+ case 'dismiss':
+ $this->UpdateOnDismiss();
+ break;
+
+ case 'profile':
+ $this->UpdateOnDismiss();
+ pl_redirect('profile/edit');
+ break;
+
+ case 'photo':
+ $this->UpdateOnDismiss();
+ pl_redirect('photo/change');
+ break;
+
+ case 'geoloc':
+ $this->UpdateOnDismiss();
+ pl_redirect('profile/edit/adresses');
+ break;
+ }
+ }
+
+ public function Prepare(&$page)
+ {
+ parent::Prepare($page);
+
+ $res = XDB::query('SELECT date < DATE_SUB(NOW(), INTERVAL 365 DAY) AS is_profile_old,
+ date AS profile_date, LENGTH(p.attach) > 0 AS has_photo
+ FROM auth_user_md5 AS u
+ LEFT JOIN photo AS p ON (u.user_id = p.uid)
+ WHERE user_id = {?}',
+ $this->user->id());
+ list($is_profile_old, $profile_date, $has_photo) = $res->fetchOneRow();
+
+ $page->assign('profile_incitation', $is_profile_old);
+ $page->assign('profile_last_update', $profile_date);
+ $page->assign('photo_incitation', !$has_photo);
+
+ $res = XDB::query('SELECT COUNT(*)
+ FROM profile_addresses
+ WHERE pid = {?} AND accuracy = 0'
+ $this->user->id());
+ $page->assign('geocoding_incitation', $res->fetchOneCell());
+ }
+
+ public function template()
+ {
+ return 'reminder/profile_update.tpl';
+ }
+ public function title()
+ {
+ return "Mise à jour de ton profil";
+ }
+ public function warning()
+ {
+ return true;
+ }
+
+ public static function IsCandidate(User &$user, $candidate)
+ {
+ $res = XDB::query('SELECT date < DATE_SUB(NOW(), INTERVAL 365 DAY) AS is_profile_old,
+ p.attach AS photo
+ FROM auth_user_md5 AS u
+ LEFT JOIN photo AS p ON (u.user_id = p.uid)
+ WHERE user_id = {?}',
+ $user->id());
+ list($is_profile_old, $has_photo) = $res->fetchOneRow();
+
+ $res = XDB::query('SELECT COUNT(*)
+ FROM profile_addresses
+ WHERE pid = {?} AND accuracy = 0'
+ $this->user->id());
+
+ return ($res->fetchOneCell() || !$has_photo || $is_profile_old);
+ }
+}
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
--- /dev/null
+<?php
+/***************************************************************************
+ * Copyright (C) 2003-2009 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 *
+ ***************************************************************************/
+
+class ReminderPromotionMl extends Reminder
+{
+ public function HandleAction($action)
+ {
+ switch ($action) {
+ case 'yes':
+ $res = XDB::query('SELECT id
+ FROM groupex.asso
+ WHERE diminutif = {?}',
+ S::v('promo'));
+ $asso_id = $res->fetchOneCell();
+ XDB::execute('REPLACE INTO groupex.membres (uid, asso_id)
+ VALUES ({?}, {?})',
+ S::v('uid'), $asso_id);
+ $mmlist = new MMList(S::v('uid'), S::v('password'));
+ $mmlist->subscribe('promo' . S::v('promo'));
+
+ $this->UpdateOnYes();
+ break;
+
+ case 'dismiss':
+ $this->UpdateOnDismiss();
+ break;
+
+ case 'no':
+ $this->UpdateOnNo();
+ break;
+ }
+ }
+
+ public function text()
+ {
+ return "La liste de diffusion de ta promotion permet de recevoir les
+ informations plus spécifiques de ta promotion pour pouvoir
+ participer plus facilement aux événements qu'elle organise. Tu
+ seras aussi inscrit dans le groupe de la promotion " .
+ $this->user->promo() . '.';
+ }
+ public function title()
+ {
+ return "Inscription à la liste de diffusion de ta promotion";
+ }
+
+ public static function IsCandidate(User &$user, $candidate)
+ {
+ // We only test if the user is in her promotion group for it is too
+ // expensive to check if she is in the corresponding ML as well.
+ $res = XDB::query('SELECT COUNT(*)
+ FROM groupex.membres
+ WHERE uid = {?} AND asso_id = (SELECT id
+ FROM groupex.asso
+ WHERE diminutif = {?})',
+ $user->id(), S::v('promo'));
+
+ $mlCount = $res->fetchOneCell();
+ if ($mlCount) {
+ Reminder::MarkCandidateAsAccepted($user->id(), $candidate);
+ }
+ return ($mlCount == 0);
+ }
+}
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
function kill_sessions()
{
- assert(S::has_perms());
+ assert(S::admin());
shell_exec('sudo -u root ' . dirname(dirname(__FILE__)) . '/bin/kill_sessions.sh');
}
$where .= "name LIKE '%" . $name_array[$i] . "%'";
}
}
- $res = XDB::iterator("SELECT name
- FROM profile_job_enum
- WHERE "
- . $where);
+ $res = XDB::iterator('SELECT name
+ FROM profile_job_enum
+ WHERE ' . $where);
$this->suggestions = "| ";
while ($sug = $res->next()) {
$this->suggestions .= $sug['name'] . " | ";
public function commit()
{
+ // TODO: use address and phone classes to update profile_job_enum and profile_phones once they are done.
+
$res = XDB::query('SELECT id
FROM profile_job_enum
WHERE name = {?}',
VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?})',
$this->name, $this->acronym, $this->url, $this->email,
$this->holdingid, $this->NAF_code, $this->AX_code);
+
$jobid = XDB::insertId();
$display_tel = format_display_number($this->tel, $error_tel);
$display_fax = format_display_number($this->fax, $error_fax);
- XDB::execute('INSERT INTO profile_phones (uid, link_type, link_id, tel_id, tel_type,
+ XDB::execute("INSERT INTO profile_phones (uid, link_type, link_id, tel_id, tel_type,
search_tel, display_tel, pub)
- VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}),
- ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})',
- $jobid, 'hq', $this->id, 0, 'fixed', format_phone_number($this->tel), $display_tel, 'public',
- $jobid, 'hq', $this->id, 1, 'fax', format_phone_number($this->fax), $display_fax, 'public');
+ VALUES ({?}, 'hq', 0, 0, 'fixed', {?}, {?}, 'public'),
+ ({?}, 'hq', 0, 1, 'fax', {?}, {?}, 'public')",
+ $jobid, format_phone_number($this->tel), $display_tel,
+ $jobid, format_phone_number($this->fax), $display_fax);
+
+ $gmapsGeocoder = new GMapsGeocoder();
+ $address = $gmapsGeocoder->getGeocodedAddress($this->address);
+ Geocoder::getAreaId($address, 'administrativeArea');
+ Geocoder::getAreaId($address, 'subAdministrativeArea');
+ Geocoder::getAreaId($address, 'locality');
XDB::execute("INSERT INTO profile_addresses (jobid, type, id, accuracy,
text, postalText, postalCode, localityId,
subAdministrativeAreaId, administrativeAreaId,
public $unique = true;
- public $promo_sortie;
+ public $oldGradYear;
+ public $newGradYear;
+ public $entryYear;
public $rules = "À priori accepter (la validation sert à repousser les
petits malins). Refuse si tu connais la personne et que tu es sûr
// }}}
// {{{ constructor
- public function __construct(User &$_user, $_sortie)
+ public function __construct(User &$_user, $_newGradYear)
{
parent::__construct($_user, true, 'orange');
- $this->promo_sortie = $_sortie;
+ $this->newGradYear = $_newGradYear;
$res = XDB::query("SELECT entry_year
FROM profile_education
- WHERE uid = {?} AND FIND_IN_SET('primary', flags)", $_uid);
- $this->promo = $res->fetchOneCell();
+ WHERE uid = {?} AND FIND_IN_SET('primary', flags)", $this->user->id());
+ $this->entryYear = $res->fetchOneCell();
+ $this->oldGradYear = $this->entryYear + 3;
}
// }}}
{
XDB::execute("UPDATE profile_education
SET grad_year = {?}
- WHERE uid = {?} AND FIND_IN_SET('primary', flags)", $this->promo_sortie, $this->uid);
+ WHERE uid = {?} AND FIND_IN_SET('primary', flags)", $this->newGradYear, $this->user->id());
return true;
}
$mailer->assign('payment', $id);
$mailer->assign('prenom', $u['prenom']);
$mailer->assign('topay', $topay);
- $mailer->assign('to', $u['email']);
+
+ if (strpos($u['email'], '@') === false) {
+ $mailer->assign('to', $u['email'] . '@' . $globals->mail->domain);
+ } else {
+ $mailer->assign('to', $u['email']);
+ }
$mailer->send();
}
}
// Pro
if (!empty($user['adr_pro'])) {
foreach ($user['adr_pro'] as $pro) {
- $street = array($adr['adr1']);
+ $street = array($pro['adr1']);
if (!empty($pro['adr2'])) {
$street[] = $pro['adr2'];
}
function handlers()
{
return array(
- 'phpinfo' => $this->make_hook('phpinfo', AUTH_MDP, 'admin'),
- 'get_rights' => $this->make_hook('get_rights', AUTH_MDP, 'admin'),
- 'admin' => $this->make_hook('default', AUTH_MDP, 'admin'),
- 'admin/ax-xorg' => $this->make_hook('ax_xorg', AUTH_MDP, 'admin'),
- 'admin/dead-but-active' => $this->make_hook('dead_but_active', AUTH_MDP, 'admin'),
- 'admin/deaths' => $this->make_hook('deaths', AUTH_MDP, 'admin'),
- 'admin/downtime' => $this->make_hook('downtime', AUTH_MDP, 'admin'),
- 'admin/homonyms' => $this->make_hook('homonyms', AUTH_MDP, 'admin'),
- 'admin/logger' => $this->make_hook('logger', AUTH_MDP, 'admin'),
- 'admin/logger/actions' => $this->make_hook('logger_actions', AUTH_MDP, 'admin'),
- 'admin/postfix/blacklist' => $this->make_hook('postfix_blacklist', AUTH_MDP, 'admin'),
- 'admin/postfix/delayed' => $this->make_hook('postfix_delayed', AUTH_MDP, 'admin'),
+ 'phpinfo' => $this->make_hook('phpinfo', AUTH_MDP, 'admin'),
+ 'get_rights' => $this->make_hook('get_rights', AUTH_MDP, 'admin'),
+ 'admin' => $this->make_hook('default', AUTH_MDP, 'admin'),
+ 'admin/ax-xorg' => $this->make_hook('ax_xorg', AUTH_MDP, 'admin'),
+ 'admin/dead-but-active' => $this->make_hook('dead_but_active', AUTH_MDP, 'admin'),
+ 'admin/deaths' => $this->make_hook('deaths', AUTH_MDP, 'admin'),
+ 'admin/downtime' => $this->make_hook('downtime', AUTH_MDP, 'admin'),
+ 'admin/homonyms' => $this->make_hook('homonyms', AUTH_MDP, 'admin'),
+ 'admin/logger' => $this->make_hook('logger', AUTH_MDP, 'admin'),
+ 'admin/logger/actions' => $this->make_hook('logger_actions', AUTH_MDP, 'admin'),
+ 'admin/postfix/blacklist' => $this->make_hook('postfix_blacklist', AUTH_MDP, 'admin'),
+ 'admin/postfix/delayed' => $this->make_hook('postfix_delayed', AUTH_MDP, 'admin'),
'admin/postfix/regexp_bounces' => $this->make_hook('postfix_regexpsbounces', AUTH_MDP, 'admin'),
- 'admin/postfix/whitelist' => $this->make_hook('postfix_whitelist', AUTH_MDP, 'admin'),
- 'admin/mx/broken' => $this->make_hook('mx_broken', AUTH_MDP, 'admin'),
- 'admin/skins' => $this->make_hook('skins', AUTH_MDP, 'admin'),
- 'admin/synchro_ax' => $this->make_hook('synchro_ax', AUTH_MDP, 'admin'),
- 'admin/user' => $this->make_hook('user', AUTH_MDP, 'admin'),
- 'admin/promo' => $this->make_hook('promo', AUTH_MDP, 'admin'),
- 'admin/validate' => $this->make_hook('validate', AUTH_MDP, 'admin'),
- 'admin/validate/answers' => $this->make_hook('validate_answers', AUTH_MDP, 'admin'),
- 'admin/wiki' => $this->make_hook('wiki', AUTH_MDP, 'admin'),
- 'admin/ipwatch' => $this->make_hook('ipwatch', AUTH_MDP, 'admin'),
- 'admin/icons' => $this->make_hook('icons', AUTH_MDP, 'admin'),
- 'admin/accounts' => $this->make_hook('accounts', AUTH_MDP, 'admin'),
- 'admin/account/types' => $this->make_hook('account_types', AUTH_MDP, 'admin'),
- 'admin/jobs' => $this->make_hook('jobs', AUTH_MDP, 'admin'),
+ 'admin/postfix/whitelist' => $this->make_hook('postfix_whitelist', AUTH_MDP, 'admin'),
+ 'admin/mx/broken' => $this->make_hook('mx_broken', AUTH_MDP, 'admin'),
+ 'admin/skins' => $this->make_hook('skins', AUTH_MDP, 'admin'),
+ 'admin/synchro_ax' => $this->make_hook('synchro_ax', AUTH_MDP, 'admin'),
+ 'admin/user' => $this->make_hook('user', AUTH_MDP, 'admin'),
+ 'admin/promo' => $this->make_hook('promo', AUTH_MDP, 'admin'),
+ 'admin/validate' => $this->make_hook('validate', AUTH_MDP, 'admin'),
+ 'admin/validate/answers' => $this->make_hook('validate_answers', AUTH_MDP, 'admin'),
+ 'admin/wiki' => $this->make_hook('wiki', AUTH_MDP, 'admin'),
+ 'admin/ipwatch' => $this->make_hook('ipwatch', AUTH_MDP, 'admin'),
+ 'admin/icons' => $this->make_hook('icons', AUTH_MDP, 'admin'),
+ 'admin/accounts' => $this->make_hook('accounts', AUTH_MDP, 'admin'),
+ 'admin/account/types' => $this->make_hook('account_types', AUTH_MDP, 'admin'),
+ 'admin/jobs' => $this->make_hook('jobs', AUTH_MDP, 'admin'),
);
}
$sql = XDB::iterator(
"SELECT crc, nb, update_time, create_time,
- FIND_IN_SET('del', release) AS del,
- FIND_IN_SET('ok', release) AS ok
- FROM postfix_mailseen
+ FIND_IN_SET('del', p.release) AS del,
+ FIND_IN_SET('ok', p.release) AS ok
+ FROM postfix_mailseen AS p
WHERE nb >= 30
- ORDER BY release != ''");
+ ORDER BY p.release != ''");
$page->assign_by_ref('mails', $sql);
}
$page->assign('bans', $bans);
}
- function getHruid($line, $partial_result, $key)
+ function getHruid($line, $key, $relation)
{
- if (!isset($partial_result['nom']) ||
- !isset($partial_result['prenom']) ||
- !isset($partial_result['promo'])) {
- return null;
+ $prenom = CSVImporter::getValue($line, 'prenom', $relation['prenom']);
+ $nom = CSVImporter::getValue($line, 'nom', $relation['nom']);
+ $promo = CSVImporter::getValue($line, 'promo', $relation['promo']);
+
+ if ($prenom != 'NULL' && $nom != 'NULL' && $promo != 'NULL') {
+ return make_forlife($prenom, $nom, $promo);
}
- return make_forlife($partial_result['prenom'], $partial_result['nom'], $partial_result['promo']);
+ return null;
}
- function getMatricule($line, $key)
+ function getMatricule($line, $key, $relation)
{
$mat = $line['matricule'];
$year = intval(substr($mat, 0, 3));
$fields = array('hruid', 'nom', 'nom_ini', 'prenom', 'naissance_ini',
'prenom_ini', 'promo', 'promo_sortie', 'flags',
'matricule', 'matricule_ax', 'perms');
+ $importer->forceValue('hruid', array($this, 'getHruid'));
$importer->forceValue('promo', $promo);
$importer->forceValue('promo_sortie', $promo + 3);
- // The hruid generation callback is set last, so that it is called once 'promo'
- // has already been computed for that line.
- $importer->forceValue('hruid', array($this, 'getHruid'));
break;
case 'ax':
$fields = array('matricule', 'matricule_ax');
}
if (Env::has('edit')) {
+ // TODO: use address and phone classes to update profile_job_enum and profile_phones once they are done.
+
S::assert_xsrf_token();
$selectedJob = Env::has('selectedJob');
+ XDB::execute("DELETE FROM profile_phones
+ WHERE uid = {?} AND link_type = 'hq'",
+ $id);
+ XDB::execute("DELETE FROM profile_addresses
+ WHERE jobid = {?} AND type = 'hq'",
+ $id);
+ XDB::execute('DELETE FROM profile_job_enum
+ WHERE id = {?}',
+ $id);
+
if (Env::has('change')) {
XDB::execute('UPDATE profile_job
SET jobid = {?}
WHERE jobid = {?}',
Env::i('newJobId'), $id);
- XDB::execute('DELETE FROM profile_job_enum
- WHERE id = {?}',
- $id);
$page->trigSuccess("L'entreprise a bien été remplacée.");
} else {
+ require_once 'profil.func.inc.php';
+ require_once 'geocoding.inc.php';
+
+ $display_tel = format_display_number(Env::v('tel'), $error_tel);
+ $display_fax = format_display_number(Env::v('fax'), $error_fax);
+ $gmapsGeocoder = new GMapsGeocoder();
+ $address = array('text' => Env::t('address'));
+ $address = $gmapsGeocoder->getGeocodedAddress($address);
+ Geocoder::getAreaId($address, 'administrativeArea');
+ Geocoder::getAreaId($address, 'subAdministrativeArea');
+ Geocoder::getAreaId($address, 'locality');
+
XDB::execute('UPDATE profile_job_enum
SET name = {?}, acronym = {?}, url = {?}, email = {?},
NAF_code = {?}, AX_code = {?}, holdingid = {?}
Env::t('name'), Env::t('acronym'), Env::t('url'), Env::t('email'),
Env::t('NAF_code'), Env::i('AX_code'), Env::i('holdingId'), $id);
+ XDB::execute("INSERT INTO profile_phones (uid, link_type, link_id, tel_id, tel_type,
+ search_tel, display_tel, pub)
+ VALUES ({?}, 'hq', 0, 0, 'fixed', {?}, {?}, 'public'),
+ ({?}, 'hq', 0, 1, 'fax', {?}, {?}, 'public')",
+ $id, format_phone_number(Env::v('tel')), $display_tel,
+ $id, format_phone_number(Env::v('fax')), $display_fax);
+
+ XDB::execute("INSERT INTO profile_addresses (jobid, type, id, accuracy,
+ text, postalText, postalCode, localityId,
+ subAdministrativeAreaId, administrativeAreaId,
+ countryId, latitude, longitude, updateTime,
+ north, south, east, west)
+ VALUES ({?}, 'hq', 0, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?},
+ {?}, {?}, FROM_UNIXTIME({?}), {?}, {?}, {?}, {?})",
+ $id, $address['accuracy'], $address['text'], $address['postalText'],
+ $address['postalCode'], $address['localityId'],
+ $address['subAdministrativeAreaId'], $address['administrativeAreaId'],
+ $address['countryId'], $address['latitude'], $address['longitude'],
+ $address['updateTime'], $address['north'], $address['south'],
+ $address['east'], $address['west']);
+
$page->trigSuccess("L'entreprise a bien été mise à jour.");
}
}
if (!Env::has('change') && $id != -1) {
- $res = XDB::query('SELECT e.id, e.name, e.acronym, e.url, e.email, e.NAF_code, e.AX_code,
- h.id AS holdingId, h.name AS holdingName, h.acronym AS holdingAcronym
- FROM profile_job_enum AS e
- LEFT JOIN profile_job_enum AS h ON (e.holdingid = h.id)
- WHERE e.id = {?}',
+ $res = XDB::query("SELECT e.id, e.name, e.acronym, e.url, e.email, e.NAF_code, e.AX_code,
+ h.id AS holdingId, h.name AS holdingName, h.acronym AS holdingAcronym,
+ t.display_tel AS tel, f.display_tel AS fax, a.text AS address
+ FROM profile_job_enum AS e
+ LEFT JOIN profile_job_enum AS h ON (e.holdingid = h.id)
+ LEFT JOIN profile_phones AS t ON (t.uid = e.id AND link_type = 'hq' AND tel_id = 0)
+ LEFT JOIN profile_phones AS f ON (f.uid = e.id AND link_type = 'hq' AND tel_id = 1)
+ LEFT JOIN profile_addresses AS a ON (a.jobid = e.id AND a.type = 'hq')
+ WHERE e.id = {?}",
$id);
if ($res->numRows() == 0) {
function handlers()
{
return array(
- 'groupex/donne-chall.php'
- => $this->make_hook('chall', AUTH_PUBLIC),
- 'groupex/export-econfiance.php'
- => $this->make_hook('econf', AUTH_PUBLIC, 'user', NO_HTTPS),
-
- 'webservices/manageurs.php'
- => $this->make_hook('manageurs', AUTH_PUBLIC, 'user', NO_HTTPS),
-
- 'auth-redirect.php' => $this->make_hook('redirect', AUTH_COOKIE),
- 'auth-groupex.php' => $this->make_hook('groupex_old', AUTH_COOKIE),
- 'auth-groupex' => $this->make_hook('groupex', AUTH_COOKIE),
- 'admin/auth-groupes-x' => $this->make_hook('admin_authgroupesx', AUTH_MDP, 'admin'),
+ 'groupex/donne-chall.php' => $this->make_hook('chall', AUTH_PUBLIC),
+ 'groupex/export-econfiance.php' => $this->make_hook('econf', AUTH_PUBLIC, 'user', NO_HTTPS),
+
+ 'webservices/manageurs.php' => $this->make_hook('manageurs', AUTH_PUBLIC, 'user', NO_HTTPS),
+
+ 'auth-redirect.php' => $this->make_hook('redirect', AUTH_COOKIE),
+ 'auth-groupex.php' => $this->make_hook('groupex_old', AUTH_COOKIE),
+ 'auth-groupex' => $this->make_hook('groupex', AUTH_COOKIE),
+ 'admin/auth-groupes-x' => $this->make_hook('admin_authgroupesx', AUTH_MDP, 'admin'),
);
}
$gpex_url .= "&PHPSESSID=" . $_GET["session"];
}
- /* a-t-on besoin d'ajouter le http:// ? */
+ // Normalize the return URL.
if (!preg_match("/^(http|https):\/\/.*/",$gpex_url)) {
$gpex_url = "http://$gpex_url";
}
$gpex_challenge = $_GET["challenge"];
- // mise à jour de l'heure et de la machine de dernier login sauf quand on est en suid
+ // Update the last login information (unless the user is in SUID).
$uid = S::i('uid');
if (!S::suid()) {
global $platal;
S::logger($uid)->log('connexion_auth_ext', $platal->path);
}
- /* on parcourt les entrees de groupes_auth */
+ // Iterate over the auth token to find which one did sign the request.
$res = XDB::iterRow('SELECT privkey, name, datafields, returnurls FROM groupesx_auth');
-
while (list($privkey,$name,$datafields,$returnurls) = $res->next()) {
if (md5($gpex_challenge.$privkey) == $gpex_pass) {
$returnurls = trim($returnurls);
+ // We check that the return url matches a per-key regexp to prevent
+ // replay attacks (more exactly to force replay attacks to redirect
+ // the user to the real GroupeX website, which defeats the attack).
if (empty($returnurls) || @preg_match($returnurls, $gpex_url)) {
$returl = $gpex_url . gpex_make_params($gpex_challenge, $privkey, $datafields, $charset);
http_redirect($returl);
+ } else if (S::admin()) {
+ $page->kill("La requête d'authentification a échouée (url de retour invalide).");
}
}
}
- /* si on n'a pas trouvé, on renvoit sur x.org */
- http_redirect('https://www.polytechnique.org/');
+ // Otherwise (if no valid request was found, or if the return URL is not
+ // acceptable), the user is redirected back to our homepage.
+ pl_redirect('/');
}
function handler_admin_authgroupesx(&$page, $action = 'list', $id = null)
foreach ($fieldarr as $val) {
// Determine the requested value, and add it to the answer.
if ($val == 'perms') {
- $params .= gpex_prepare_param($val, S::has_perms() ? 'admin' : 'user', $tohash, $charset);
+ $params .= gpex_prepare_param($val, S::admin() ? 'admin' : 'user', $tohash, $charset);
} else if ($val == 'forlife') {
$params .= gpex_prepare_param($val, S::v('hruid'), $tohash, $charset);
} else if (S::has($val)) {
$perms = $res->fetchOneCell();
} else {
// if no group asked, return main rights
- $perms = S::has_perms() ? 'admin' : 'membre';
+ $perms = S::admin() ? 'admin' : 'membre';
}
$params .= gpex_prepare_param($val, $perms, $tohash, $charset);
} else {
function handlers()
{
return array(
- 'ax' => $this->make_hook('index', AUTH_COOKIE),
+ 'ax' => $this->make_hook('index', AUTH_COOKIE),
'ax/out' => $this->make_hook('out', AUTH_PUBLIC),
'ax/show' => $this->make_hook('show', AUTH_COOKIE),
'ax/edit' => $this->make_hook('submit', AUTH_MDP),
'ax/edit/cancel' => $this->make_hook('cancel', AUTH_MDP),
'ax/edit/valid' => $this->make_hook('valid', AUTH_MDP),
- 'admin/axletter' => $this->make_hook('admin', AUTH_MDP, 'admin'),
+ 'admin/axletter' => $this->make_hook('admin', AUTH_MDP, 'admin'),
);
}
$signature = trim(Post::v('signature'));
$promo_min = Post::i('promo_min');
$promo_max = Post::i('promo_max');
+ $subset_to = preg_split("/[ ,;\:\n\r]+/", Post::v('subset_to'), -1, PREG_SPLIT_NO_EMPTY);
+ $subset = (count($subset_to) > 0);
$echeance = Post::has('echeance_date') ?
preg_replace('/^(\d\d\d\d)(\d\d)(\d\d)$/', '\1-\2-\3', Post::v('echeance_date')) . ' ' . Post::v('echeance_time')
: Post::v('echeance');
$res = XDB::query("SELECT * FROM axletter WHERE FIND_IN_SET('new', bits)");
if ($res->numRows()) {
extract($res->fetchOneAssoc(), EXTR_OVERWRITE);
+ $subset_to = explode("\n", $subset);
+ $subset = (count($subset_to) > 0);
$saved = true;
} else {
XDB::execute("INSERT INTO axletter SET id = NULL");
case 'Aperçu':
$this->load('axletter.inc.php');
$al = new AXLetter(array($id, $short_name, $subject, $title, $body, $signature,
- $promo_min, $promo_max, $echeance, 0, 'new'));
+ $promo_min, $promo_max, $subset, $echeance, 0, 'new'));
$al->toHtml($page, S::v('prenom'), S::v('nom'), S::v('femme'));
break;
case 'Confirmer':
XDB::execute("REPLACE INTO axletter
SET id = {?}, short_name = {?}, subject = {?}, title = {?}, body = {?},
- signature = {?}, promo_min = {?}, promo_max = {?}, echeance = {?}",
- $id, $short_name, $subject, $title, $body, $signature, $promo_min, $promo_max, $echeance);
+ signature = {?}, promo_min = {?}, promo_max = {?}, echeance = {?}, subset = {?}",
+ $id, $short_name, $subject, $title, $body, $signature, $promo_min, $promo_max, $echeance, $subset ? implode("\n", $subset_to): null);
if (!$saved) {
global $globals;
$mailer = new PlMailer();
$page->assign('signature', $signature);
$page->assign('promo_min', $promo_min);
$page->assign('promo_max', $promo_max);
+ $page->assign('subset_to', implode("\n", $subset_to));
+ $page->assign('subset', $subset);
$page->assign('echeance', $echeance);
$page->assign('echeance_date', $echeance_date);
$page->assign('echeance_time', $echeance_time);
$page->assign('saved', $saved);
$page->assign('new', $new);
- $page->assign('is_xorg', S::has_perms());
+ $page->assign('is_xorg', S::admin());
if (!$saved) {
$select = '';
$importer->apply($page, "admin/axletter", array('user_id', 'email', 'prenom', 'nom', 'promo', 'flag', 'hash'));
}
- function idFromMail($line, $key)
+ function idFromMail($line, $key, $relation = null)
{
static $field;
global $globals;
return count($id) == 1 ? $id[0] : 0;
}
- function createHash($line, $partial_result, $key)
+ function createHash($line, $key, $relation)
{
$hash = implode(time(), $line) . rand();
$hash = md5($hash);
public $_signature;
public $_promo_min;
public $_promo_max;
+ public $_subset;
+ public $_subset_to;
public $_echeance;
public $_date;
public $_bits;
}
list($this->_id, $this->_shortname, $this->_title_mail, $this->_title,
$this->_body, $this->_signature, $this->_promo_min, $this->_promo_max,
- $this->_echeance, $this->_date, $this->_bits) = $id;
+ $this->_subset_to, $this->_echeance, $this->_date, $this->_bits) = $id;
if ($this->_date == '0000-00-00') {
$this->_date = 0;
}
+ $this->_subset_to = explode("\n", $this->_subset_to);
+ $this->_subset = (count($this->_subset_to) > 0);
}
protected function assignData(&$smarty)
static public function hasPerms()
{
- if (S::has_perms()) {
+ if (S::admin()) {
return true;
}
- $res = XDB::query("SELECT 1
+ $res = XDB::query("SELECT COUNT(*)
FROM axletter_rights
WHERE user_id = {?}", S::i('uid'));
- return $res->fetchOneCell();
+ return ($res->fetchOneCell() > 0);
}
static public function grantPerms($uid)
protected function subscriptionWhere()
{
- if (!$this->_promo_min && !$this->_promo_max) {
+ if (!$this->_promo_min && !$this->_promo_max && !$this->_subset) {
return '1';
}
$where = array();
if ($this->_promo_max) {
$where[] = "((ni.user_id = 0 AND ni.promo <= {$this->_promo_max}) OR (ni.user_id != 0 AND u.promo <= {$this->_promo_max}))";
}
+ if ($this->_subset) {
+ require_once("emails.inc.php");
+ $ids = ids_from_mails($this->_subset_to);
+ $ids_list = implode(',', $ids);
+ if(count($ids_list) > 0) {
+ $where[] = "ni.user_id IN ($ids_list)";
+ } else {
+ // No valid email
+ $where[] = "0";
+ }
+ }
return implode(' AND ', $where);
}
function handlers()
{
return array(
- 'bandeau/icone.png' => $this->make_hook('icone',AUTH_PUBLIC, 'user', NO_HTTPS),
- 'bandeau' => $this->make_hook('html', AUTH_PUBLIC, 'user', NO_HTTPS),
- 'bandeau.css' => $this->make_hook('css', AUTH_PUBLIC, 'user', NO_HTTPS),
+ 'bandeau/icone.png' => $this->make_hook('icone', AUTH_PUBLIC, 'user', NO_HTTPS),
+ 'bandeau' => $this->make_hook('html', AUTH_PUBLIC, 'user', NO_HTTPS),
+ 'bandeau.css' => $this->make_hook('css', AUTH_PUBLIC, 'user', NO_HTTPS),
);
}
'carnet/notifs' => $this->make_hook('notifs', AUTH_COOKIE),
'carnet/contacts' => $this->make_hook('contacts', AUTH_COOKIE),
- 'carnet/contacts/pdf' => $this->make_hook('pdf', AUTH_COOKIE, 'user', NO_HTTPS),
+ 'carnet/contacts/pdf' => $this->make_hook('pdf', AUTH_COOKIE),
+ 'carnet/contacts/vcard' => $this->make_hook('vcard', AUTH_COOKIE),
'carnet/contacts/ical' => $this->make_hook('ical', AUTH_PUBLIC, 'user', NO_HTTPS),
- 'carnet/contacts/vcard' => $this->make_hook('vcard', AUTH_COOKIE, 'user', NO_HTTPS),
'carnet/rss' => $this->make_hook('rss', AUTH_PUBLIC, 'user', NO_HTTPS),
);
function handlers()
{
return array(
- 'emails' => $this->make_hook('emails', AUTH_COOKIE),
- 'emails/alias' => $this->make_hook('alias', AUTH_MDP),
- 'emails/antispam' => $this->make_hook('antispam', AUTH_MDP),
- 'emails/broken' => $this->make_hook('broken', AUTH_COOKIE),
- 'emails/redirect' => $this->make_hook('redirect', AUTH_MDP),
- 'emails/send' => $this->make_hook('send', AUTH_MDP),
- 'emails/antispam/submit' => $this->make_hook('submit', AUTH_COOKIE),
- 'emails/test' => $this->make_hook('test', AUTH_COOKIE, 'user', NO_AUTH),
-
- 'emails/rewrite/in' => $this->make_hook('rewrite_in', AUTH_PUBLIC),
- 'emails/rewrite/out' => $this->make_hook('rewrite_out', AUTH_PUBLIC),
-
- 'emails/imap/in' => $this->make_hook('imap_in', AUTH_PUBLIC),
-
- 'admin/emails/duplicated' => $this->make_hook('duplicated', AUTH_MDP, 'admin'),
- 'admin/emails/watch' => $this->make_hook('duplicated', AUTH_MDP, 'admin'),
- 'admin/emails/lost' => $this->make_hook('lost', AUTH_MDP, 'admin'),
+ 'emails' => $this->make_hook('emails', AUTH_COOKIE),
+ 'emails/alias' => $this->make_hook('alias', AUTH_MDP),
+ 'emails/antispam' => $this->make_hook('antispam', AUTH_MDP),
+ 'emails/broken' => $this->make_hook('broken', AUTH_COOKIE),
+ 'emails/redirect' => $this->make_hook('redirect', AUTH_MDP),
+ 'emails/send' => $this->make_hook('send', AUTH_MDP),
+ 'emails/antispam/submit' => $this->make_hook('submit', AUTH_COOKIE),
+ 'emails/test' => $this->make_hook('test', AUTH_COOKIE, 'user', NO_AUTH),
+
+ 'emails/rewrite/in' => $this->make_hook('rewrite_in', AUTH_PUBLIC),
+ 'emails/rewrite/out' => $this->make_hook('rewrite_out', AUTH_PUBLIC),
+
+ 'emails/imap/in' => $this->make_hook('imap_in', AUTH_PUBLIC),
+
+ 'admin/emails/duplicated' => $this->make_hook('duplicated', AUTH_MDP, 'admin'),
+ 'admin/emails/watch' => $this->make_hook('duplicated', AUTH_MDP, 'admin'),
+ 'admin/emails/lost' => $this->make_hook('lost', AUTH_MDP, 'admin'),
);
}
}
// Retrieves the User object for the test email recipient.
- if (S::has_perms() && $hruid) {
+ if (S::admin() && $hruid) {
$user = User::getSilent($hruid);
} else {
$user = S::user();
function handlers()
{
return array(
- 'events' => $this->make_hook('ev', AUTH_COOKIE),
- 'rss' => $this->make_hook('rss', AUTH_PUBLIC, 'user', NO_HTTPS),
- 'events/preview' => $this->make_hook('preview', AUTH_PUBLIC, 'user', NO_AUTH),
- 'events/photo' => $this->make_hook('photo', AUTH_PUBLIC),
- 'events/submit' => $this->make_hook('ev_submit', AUTH_MDP),
- 'admin/events' => $this->make_hook('admin_events', AUTH_MDP, 'admin'),
-
- 'ajax/tips' => $this->make_hook('tips', AUTH_COOKIE, 'user', NO_AUTH),
- 'admin/tips' => $this->make_hook('admin_tips', AUTH_MDP, 'admin'),
+ 'events' => $this->make_hook('ev', AUTH_COOKIE),
+ 'rss' => $this->make_hook('rss', AUTH_PUBLIC, 'user', NO_HTTPS),
+ 'events/preview' => $this->make_hook('preview', AUTH_PUBLIC, 'user', NO_AUTH),
+ 'events/photo' => $this->make_hook('photo', AUTH_PUBLIC),
+ 'events/submit' => $this->make_hook('ev_submit', AUTH_MDP),
+ 'admin/events' => $this->make_hook('admin_events', AUTH_MDP, 'admin'),
+
+ 'ajax/tips' => $this->make_hook('tips', AUTH_COOKIE, 'user', NO_AUTH),
+ 'admin/tips' => $this->make_hook('admin_tips', AUTH_MDP, 'admin'),
);
}
$page->addJsLink('ajax.js');
$page->assign('tips', $this->get_tips());
- // Profile update (appears when profile is > 400d old), and birthday
- // oneboxes.
+ // Adds a reminder onebox to the page.
$user = S::user();
+ require_once 'reminder.inc.php';
+ if (($reminder = Reminder::GetCandidateReminder($user))) {
+ $reminder->Prepare($page);
+ }
+
+ // Wishes "Happy birthday" when required
$profile = $user->profile();
if (!is_null($profile)) {
- if (strtotime($profile->last_change) < time() - (400 * 86400)) {
- $page->assign('fiche_incitation', $profile->last_change);
- }
if ($profile->next_birthday == date('Y-m-d')) {
$birthyear = (int)date('Y', strtotime($profile->birthdate));
$curyear = (int)date('Y');
}
}
- // No-photo onebox.
- $res = XDB::query("SELECT COUNT(*)
- FROM photo
- WHERE uid = {?}",
- S::user()->id());
- $page->assign('photo_incitation', $res->fetchOneCell() == 0);
-
- // Geo-location onebox.
- require_once "geocoding.inc.php";
- $page->assign('geoloc_incitation', Geocoder::countNonGeocoded(S::user()->id()));
-
// Direct link to the RSS feed, when available.
if (S::hasAuthToken()) {
$page->setRssLink('Polytechnique.org :: News',
function handlers()
{
return array(
- 'banana' => $this->make_hook('banana', AUTH_COOKIE),
- 'banana/rss' => $this->make_hook('rss', AUTH_PUBLIC, 'user', NO_HTTPS),
- 'admin/forums' => $this->make_hook('forums_bans', AUTH_MDP, 'admin'),
+ 'banana' => $this->make_hook('banana', AUTH_COOKIE),
+ 'banana/rss' => $this->make_hook('rss', AUTH_PUBLIC, 'user', NO_HTTPS),
+ 'admin/forums' => $this->make_hook('forums_bans', AUTH_MDP, 'admin'),
);
}
{
return array(
'gadgets/ig-events.xml' => $this->make_hook('ig_events_xml', AUTH_PUBLIC, 'user', NO_HTTPS),
- 'gadgets/ig-events' => $this->make_hook('ig_events', AUTH_PUBLIC),
+ 'gadgets/ig-events' => $this->make_hook('ig_events', AUTH_PUBLIC),
'gadgets/ig-search.xml' => $this->make_hook('ig_search_xml', AUTH_PUBLIC, 'user', NO_HTTPS),
- 'gadgets/ig-search' => $this->make_hook('ig_search', AUTH_PUBLIC),
+ 'gadgets/ig-search' => $this->make_hook('ig_search', AUTH_PUBLIC),
);
}
}
return array(
- 'googleapps' => $this->make_hook('index', AUTH_MDP),
- 'admin/googleapps' => $this->make_hook('admin', AUTH_MDP. 'admin'),
- 'admin/googleapps/job' => $this->make_hook('admin_job', AUTH_MDP, 'admin'),
+ 'googleapps' => $this->make_hook('index', AUTH_MDP),
+ 'admin/googleapps' => $this->make_hook('admin', AUTH_MDP, 'admin'),
+ 'admin/googleapps/job' => $this->make_hook('admin_job', AUTH_MDP, 'admin'),
'admin/googleapps/user' => $this->make_hook('admin_user', AUTH_MDP, 'admin'),
);
}
{
return array(
'lists' => $this->make_hook('lists', AUTH_MDP),
- 'lists/ajax' => $this->make_hook('ajax', AUTH_MDP, 'user', NO_AUTH),
+ 'lists/ajax' => $this->make_hook('ajax', AUTH_MDP, 'user', NO_AUTH),
'lists/create' => $this->make_hook('create', AUTH_MDP),
'lists/members' => $this->make_hook('members', AUTH_COOKIE),
'lists/soptions' => $this->make_hook('soptions', AUTH_MDP),
'lists/check' => $this->make_hook('check', AUTH_MDP),
- 'admin/lists' => $this->make_hook('admin_all', AUTH_MDP, 'admin'),
+ 'admin/lists' => $this->make_hook('admin_all', AUTH_MDP, 'admin'),
);
}
$msg = str_replace("%(listname)s", $liste, $msg);
$page->assign('msg', $msg);
return;
+ } elseif (Get::has('mid') && Env::has('mok')) {
+ $page->changeTpl('lists/moderate_mail.tpl');
+ require_once('banana/moderate.inc.php');
+ $params = array('listname' => $liste, 'domain' => $domain,
+ 'artid' => Get::i('mid'), 'part' => Get::v('part'), 'action' => Get::v('action'));
+ $params['client'] = $this->client;
+ run_banana($page, 'ModerationBanana', $params);
+
+ $msg = file_get_contents('/etc/mailman/fr/accept.txt');
+ $msg = str_replace("%(adminaddr)s", "$liste-owner@{$domain}", $msg);
+ $msg = str_replace("%(request)s", "<< SUJET DU MAIL >>", $msg);
+ $msg = str_replace("%(reason)s", "<< TON EXPLICATION >>", $msg);
+ $msg = str_replace("%(listname)s", $liste, $msg);
+ $page->assign('msg', $msg);
+ return;
}
$mail = $this->moderate_mail($domain, $liste, Env::i('mid'));
--- /dev/null
+Vous avez envoyé un message à la liste de diffusion {{{LIST}}} :
+
+ %(request)s
+
+Le modérateur a souhaité diffuser votre message vers les abonnés à
+la liste.
+
+ "%(reason)s"
+
+Toute question ou commentaire doit être adressé aux modérateurs de la
+liste à cette adresse :
+
+ {{{ALIST}}}
function handlers()
{
return array(
- 'nl' => $this->make_hook('nl', AUTH_COOKIE),
- 'nl/show' => $this->make_hook('nl_show', AUTH_COOKIE),
- 'nl/submit' => $this->make_hook('nl_submit', AUTH_MDP),
- 'admin/newsletter' => $this->make_hook('admin_nl', AUTH_MDP, 'admin'),
- 'admin/newsletter/categories' => $this->make_hook('admin_nl_cat', AUTH_MDP, 'admin'),
+ 'nl' => $this->make_hook('nl', AUTH_COOKIE),
+ 'nl/show' => $this->make_hook('nl_show', AUTH_COOKIE),
+ 'nl/submit' => $this->make_hook('nl_submit', AUTH_MDP),
+ 'admin/newsletter' => $this->make_hook('admin_nl', AUTH_MDP, 'admin'),
+ 'admin/newsletter/categories' => $this->make_hook('admin_nl_cat', AUTH_MDP, 'admin'),
'admin/newsletter/edit' => $this->make_hook('admin_nl_edit', AUTH_MDP, 'admin'),
);
}
function handlers()
{
return array(
- 'openid' => $this->make_hook('openid', AUTH_PUBLIC),
- 'openid/trust' => $this->make_hook('trust', AUTH_COOKIE),
- 'openid/trusted' => $this->make_hook('trusted', AUTH_MDP),
- 'admin/openid/trusted' => $this->make_hook('admin_trusted', AUTH_MDP),
- 'openid/idp_xrds' => $this->make_hook('idp_xrds', AUTH_PUBLIC),
- 'openid/user_xrds' => $this->make_hook('user_xrds', AUTH_PUBLIC),
- 'openid/melix' => $this->make_hook('melix', AUTH_PUBLIC),
+ 'openid' => $this->make_hook('openid', AUTH_PUBLIC),
+ 'openid/melix' => $this->make_hook('melix', AUTH_PUBLIC),
+ 'openid/xrds' => $this->make_hook('xrds', AUTH_PUBLIC),
+ 'openid/trust' => $this->make_hook('trust', AUTH_MDP),
+ 'openid/trusted' => $this->make_hook('trusted', AUTH_MDP),
+ 'admin/openid/trusted' => $this->make_hook('admin_trusted', AUTH_MDP, 'admin'),
);
}
- function handler_openid(&$page, $x = null)
+ function handler_openid(&$page, $login = null)
{
$this->load('openid.inc.php');
+ $requested_user = User::getSilent($login);
+ $server = new OpenId();
// Spec §4.1.2: if "openid.mode" is absent, we SHOULD assume that
- // the request is not an OpenId message
- if (!array_key_exists('openid_mode', $_REQUEST)) {
- return $this->render_discovery_page($page, get_user($x));
+ // the request is not an OpenId message.
+ if (!$server->IsOpenIdRequest()) {
+ if ($requested_user) {
+ $server->RenderDiscoveryPage($page, $requested_user);
+ return;
+ } else {
+ pl_redirect('Xorg/OpenId');
+ }
+ exit;
}
- // Now, deal with the OpenId message
- $server = init_openid_server();
- $request = $server->decodeRequest();
-
- // In modes 'checkid_immediate' and 'checkid_setup', the request
- // needs some logic and can not be automatically answered by the server
-
- // Immediate mode
- if ($request->mode == 'checkid_immediate') {
+ // Initializes the OpenId environment from the request.
+ $server->Initialize();
+
+ // In modes 'checkid_immediate' and 'checkid_setup', we need to check
+ // by ourselves that we want to allow the user to be authenticated.
+ // Otherwise it can simply be forwarded to the Server object.
+ if ($server->IsAuthorizationRequest()) {
+ $authorized = S::logged() &&
+ $server->IsUserAuthorized(S::user()) &&
+ $server->IsEndpointTrusted(S::user());
+
+ if ($authorized) {
+ // TODO(vzanotti): SReg requests are currently not honored if
+ // the website is already trusted. We may want to redirect SReg
+ // requests to /openid/trust, to allow the user to choose.
+ $server->AnswerRequest(true);
+ } else if ($server->IsImmediateRequest()) {
+ $server->AnswerRequest(false);
+ } else {
+ // The user is currently not authorized to get her authorization
+ // request approved. Two possibilities:
+ // * the endpoint is not yet trusted => redirect to openid/trust
+ // * the user is not logged in => log in the user.
+ //
+ // The second case requires a special handling when the request
+ // was POSTed, as our current log in mechanism does not preserve
+ // POST arguments.
+ $openid_args = $server->GetQueryStringForRequest();
+ if (S::logged()) {
+ pl_redirect('openid/trust', $openid_args);
+ } else if (Post::has('openid_mode')) {
+ pl_redirect('openid', $openid_args);
+ } else {
+ return PL_DO_AUTH;
+ }
+ }
+ } else {
+ $server->HandleRequest();
+ }
- // We deny immediate requests, unless:
- // - the user identifier is known by the RP
- // - the user is logged in
- // - the user identifier matches the user logged in
- // - the user has whitelisted the site
- $answer = !$request->idSelect()
- && S::logged()
- && $request->identity == S::user()->login()
- && is_trusted_site(S::user(), $request->trust_root);
- $response =& $request->answer($answer);
+ // All requests should have been answered at this point. The best here
+ // is to get the user back to a safe page.
+ pl_redirect('');
+ }
- // Setup mode
- } else if ($request->mode == 'checkid_setup') {
+ function handler_melix(&$page, $login = null)
+ {
+ $this->load('openid.inc.php');
- // We redirect to a page where the user will authenticate
- // and confirm the use of his/her OpenId
- $request_id = uniqid('openid-');
- S::set($request_id, serialize($request));
- $query = 'request_id=' . urlencode($request_id);
- pl_redirect('openid/trust', $query);
- return;
+ global $globals;
+ $melix = ($login ? $login . '@' . $globals->mail->alias_dom : null);
- // Other requests can be automatically handled by the server
+ if ($melix && ($requested_user = User::getSilent($melix))) {
+ $server = new OpenId();
+ $server->RenderDiscoveryPage($page, $requested_user);
} else {
- $response =& $server->handleRequest($request);
+ pl_redirect('Xorg/OpenId');
}
-
- $webresponse =& $server->encodeResponse($response);
- $this->render_openid_response($webresponse);
}
- function handler_trust(&$page, $x = null)
+ function handler_xrds(&$page, $login = null)
{
$this->load('openid.inc.php');
+ $requested_user = User::getSilent($login);
+ $server = new OpenId();
- // Recover request in session
- $request_id = $_GET['request_id'];
- if (is_null($request_id) || !isset($_SESSION[$request_id])) {
- // There is no authentication information, something went wrong
- pl_redirect('/');
- return;
+ if (!$login) {
+ $server->RenderMainXrdsPage($page);
+ } else if ($requested_user) {
+ $server->RenderUserXrdsPage($page, $requested_user);
+ } else {
+ return PL_NOT_FOUND;
}
+ }
- require_once 'Auth/OpenID/Server.php';
- $request = unserialize($_SESSION[$request_id]);
-
- $server = init_openid_server();
+ function handler_trust(&$page)
+ {
+ $this->load('openid.inc.php');
+ $server = new OpenId();
$user = S::user();
- $identity = null;
- $claimed_id = null;
- // Set the identity to the user currently logged in
- // if an OP Identifier was initially used
- if ($request->identity == Auth_OpenID_IDENTIFIER_SELECT) {
- $identity = $user->hruid;
- $claimed_id = get_user_openid_url($user);
- // Check that the identity matches the user currently logged in
- // if an User Identifier was initially used
- } else if ($request->identity != $user->hruid) {
- $response =& $request->answer(false);
- $webresponse =& $server->encodeResponse($response);
- $this->render_openid_response($webresponse);
- return;
+ // Initializes the OpenId environment from the request.
+ if (!$server->Initialize() || !$server->IsAuthorizationRequest()) {
+ $page->kill("Ta requête OpenID a échoué, merci de réessayer.");
}
- // Prepare Simple Registration response fields
- require_once 'Auth/OpenID/SReg.php';
- $sreg_request = Auth_OpenID_SRegRequest::fromOpenIDRequest($request);
- $sreg_response = Auth_OpenID_SRegResponse::extractResponse($sreg_request, get_sreg_data($user));
+ // Prepares the SREG data, if any is required.
+ $sreg_response = $server->GetSRegDataForRequest($user);
- $whitelisted = is_trusted_site($user, $request->trust_root);
-
- // Ask the user for confirmation
- $from_trust_page = $_SERVER['REQUEST_METHOD'] == 'POST'
- && (isset($_POST['openid_trust']) || isset($_POST['openid_cancel']));
- if (!$whitelisted && !$from_trust_page) {
+ // Asks the user about her trust level of the current request, if not
+ // done yet.
+ if (!Post::has('trust_accept') && !Post::has('trust_cancel')) {
$page->changeTpl('openid/trust.tpl');
- $page->assign('relying_party', $request->trust_root);
- $page->assign_by_ref('sreg_data', $sreg_response->data);
- $query = 'request_id=' . urlencode($request_id);
- $page->assign('query', $query);
- return;
- }
-
- // If this point is reached, the user has just validated the form on the 'trust' page
+ $page->assign('openid_query', $server->GetQueryStringForRequest());
+ $page->assign('relying_party', $server->GetEndpoint());
+ $page->assign('sreg_data', $sreg_response->contents());
- // Remove the request from session since an answer will be sent
- S::kill($request_id);
-
- // Add 'always trusted' sites to whitelist
- if (isset($_POST['openid_trust']) && @$_POST['openid_always']) {
- add_trusted_site($user, $request->trust_root);
+ return;
}
- // Answer to the Relying Party
- if ($whitelisted || isset($_POST['openid_trust'])) {
- $response =& $request->answer(true, null, $identity, $claimed_id);
-
- // Add the simple registration response values to the OpenID
- // response message.
- $sreg_response->toMessage($response->fields);
-
- } else { // !$whitelisted && isset($_POST['openid_cancel'])
- $response =& $request->answer(false);
+ // Interprets the form results, and updates the user whitelist.
+ S::assert_xsrf_token();
+ $trusted = $server->UpdateEndpointTrust(
+ $user,
+ Post::b('trust_accept') && !Post::b('trust_cancel'),
+ Post::b('trust_always'));
+
+ // Finally answers the request.
+ if ($server->IsUserAuthorized($user) && $trusted) {
+ $server->AnswerRequest(
+ true, $user, Post::b('trust_sreg') ? $sreg_response : null);
+ } else {
+ $server->AnswerRequest(false);
}
-
- $webresponse =& $server->encodeResponse($response);
- $this->render_openid_response($webresponse);
}
function handler_trusted(&$page, $action = 'list', $id = null)
$page->assign('readonly', true);
$table_editor->apply($page, $action, $id);
}
-
- function handler_idp_xrds(&$page)
- {
- $this->load('openid.inc.php');
- header('Content-type: application/xrds+xml');
- $page->changeTpl('openid/idp_xrds.tpl', NO_SKIN);
- $page->assign('type2', Auth_OpenID_TYPE_2_0_IDP);
- $page->assign('sreg', Auth_OpenID_SREG_URI);
- $page->assign('provider', get_openid_url());
- }
-
- function handler_user_xrds(&$page, $x = null)
- {
- $this->load('openid.inc.php');
-
- $user = get_user($x);
- if (is_null($user)) {
- return PL_NOT_FOUND;
- }
-
- header('Content-type: application/xrds+xml');
- $page->changeTpl('openid/user_xrds.tpl', NO_SKIN);
- $page->assign('type2', Auth_OpenID_TYPE_2_0);
- $page->assign('type1', Auth_OpenID_TYPE_1_1);
- $page->assign('sreg', Auth_OpenID_SREG_URI);
- $page->assign('provider', get_openid_url());
- $page->assign('local_id', $user->hruid);
- }
-
- function handler_melix(&$page, $x = null)
- {
- $this->load('openid.inc.php');
- $user = get_user_by_alias($x);
-
- // This will redirect to the canonic URL, which was not used
- // if this hook was triggered
- return $this->render_discovery_page(&$page, $user);
- }
-
- //--------------------------------------------------------------------//
-
- function render_discovery_page(&$page, $user)
- {
-
- // Show the documentation if this is not the OpenId page of an user
- if (is_null($user)) {
- pl_redirect('Xorg/OpenId');
- }
-
- // Redirect to the canonic URL if we are using an alias
- // There might be a risk of redirection loop here
- // if $_SERVER was not exactly what we expect
- $current_url = 'http' . (empty($_SERVER['HTTPS']) ? '' : 's') . '://'
- . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
- $canonic_url = get_user_openid_url($user);
- if ($current_url != $canonic_url) {
- http_redirect($canonic_url);
- }
-
- // Include X-XRDS-Location response-header for Yadis discovery
- header('X-XRDS-Location: ' . get_user_xrds_url($user));
-
- $page->changeTpl('openid/openid.tpl');
- $page->setTitle($user->fullName());
- // Set the <link> tags for HTML-Based Discovery
- $page->addLink('openid.server openid2.provider', get_openid_url());
- $page->addLink('openid.delegate openid2.local_id', $user->hruid);
- $page->assign_by_ref('user', $user);
-
- return;
- }
-
- function render_openid_response($webresponse)
- {
- if ($webresponse->code != AUTH_OPENID_HTTP_OK) {
- header(sprintf("HTTP/1.1 %d ", $webresponse->code),
- true, $webresponse->code);
- }
- foreach ($webresponse->headers as $k => $v) {
- header("$k: $v");
- }
- header('Connection: close');
- print $webresponse->body;
- exit;
- }
}
// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
-?>
\ No newline at end of file
+?>
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
***************************************************************************/
-require_once "Auth/OpenID/Discover.php";
+require_once 'Auth/OpenID/Discover.php';
-function init_openid_server()
+// An helper class for using plat/al as an OpenId Identity Provider.
+class OpenId
{
- // Initialize a filesystem-based store
- $store_location = dirname(__FILE__) . '/../../spool/openid/store';
- require_once "Auth/OpenID/FileStore.php";
- $store = new Auth_OpenID_FileStore($store_location);
-
- // Create an OpenId server
- require_once 'Auth/OpenID/Server.php';
- return new Auth_OpenID_Server($store, get_openid_url());
-}
+ private $base_url; // Base url for all OpenId operations.
+ private $spool_store; // Location of the spool storage for OpenID.
-function get_openid_url()
-{
- global $globals;
- return $globals->baseurl . '/openid';
-}
+ private $server = null; // Auth::OpenId::Server object.
+ private $request = null; // Request extracted by the Server object.
+
+ public function __construct()
+ {
+ global $globals;
-function get_user($x) {
- if (is_null($x)) {
- return null;
+ $this->base_url = $globals->baseurl . '/openid';
+ $this->spool_store = $globals->spoolroot . '/spool/openid/store';
}
- $user = User::getSilent($x);
- return $user ? $user : null;
-}
+ // Initializes an OpenId Server object; it will use a defined spool-based
+ // directory to store OpenID secrets. Returns true on success.
+ public function Initialize()
+ {
+ require_once 'Auth/OpenID/FileStore.php';
+ require_once 'Auth/OpenID/Server.php';
+
+ $store = new Auth_OpenID_FileStore($this->spool_store);
+ $this->server = new Auth_OpenID_Server($store, $this->base_url);
+ $this->request = $this->server->decodeRequest();
-function get_user_by_alias($x) {
- if (is_null($x)) {
- return null;
+ return !is_a($this->request, 'Auth_OpenID_ServerError');
}
- global $globals;
- // Should we check the publicity of the alias?
- $user = User::getSilent($x . '@' . $globals->mail->alias_dom);
- return $user ? $user : null;
-}
+ // Authorization logic helpers ---------------------------------------------
-function get_user_openid_url($user)
-{
- if (is_null($user)) {
- return null;
+ // Returns true iff the current request is a valid openid request.
+ public function IsOpenIdRequest()
+ {
+ return Env::has('openid_mode');
}
- global $globals;
- return $globals->baseurl . '/openid/' . $user->hruid;
-}
-function get_idp_xrds_url()
-{
- global $globals;
- return $globals->baseurl . '/openid/idp_xrds';
-}
+ // Returns true iff the request needs to be handled directly by the calling
+ // code (ie. the current user needs to be authorized).
+ public function IsAuthorizationRequest()
+ {
+ return $this->request->mode == 'checkid_immediate' ||
+ $this->request->mode == 'checkid_setup';
+ }
-function get_user_xrds_url($user)
-{
- if (is_null($user)) {
- return null;
+ // Returns true iff the request requires an immediate answer (no user
+ // interaction is allowed).
+ public function IsImmediateRequest()
+ {
+ return $this->request->mode == 'checkid_immediate';
}
- global $globals;
- return $globals->baseurl . '/openid/user_xrds/' . $user->hruid;
-}
-function get_sreg_data($user)
-{
- if (is_null($user)) {
- return null;
- }
- return array('fullname' => $user->fullName(),
- 'nickname' => $user->displayName(),
- 'dob' => null,
- 'email' => $user->bestEmail(),
- 'gender' => $user->isFemale() ? 'F' : 'M',
- 'postcode' => null,
- 'country' => null,
- 'language' => null,
- 'timezone' => null);
-}
+ // Returns true iff the logged-in user is authorized for the current request.
+ // It checks that the user is logged in, and has the authorization to use
+ // that identity.
+ public function IsUserAuthorized(User $user)
+ {
+ return $user && ($user->login() == $this->request->identity ||
+ $this->request->idSelect());
+ }
-function is_trusted_site($user, $url)
-{
- $res = XDB::query('SELECT COUNT(*)
- FROM openid_trusted
- WHERE (user_id = {?} OR user_id IS NULL)
- AND url = {?}',
- $user->id(), $url);
- return $res->fetchOneCell() > 0;
-}
+ // SimpleRegistration helpers ----------------------------------------------
-function add_trusted_site($user, $url)
-{
- XDB::execute("INSERT IGNORE INTO openid_trusted
- SET user_id={?}, url={?}",
- $user->id(), $url);
+ // Determines which SREG data are requested by the endpoint, and returns them.
+ public function GetSRegDataForRequest(User &$user)
+ {
+ require_once 'Auth/OpenID/SReg.php';
+
+ // Other common SReg fields we could fill are:
+ // dob, country, language, timezone.
+ $sreg_request = Auth_OpenID_SRegRequest::fromOpenIDRequest($this->request);
+ return Auth_OpenID_SRegResponse::extractResponse($sreg_request, array(
+ 'fullname' => $user->fullName(),
+ 'nickname' => $user->displayName(),
+ 'email' => $user->bestEmail(),
+ 'gender' => $user->isFemale() ? 'F' : 'M',
+ ));
+ }
+
+ // Handling and answering helpers ------------------------------------------
+
+ // Answers the current request, and renders the response. Appends the |sreg|
+ // data when not null.
+ public function AnswerRequest($is_authorized, $user = null, $sreg_data = null)
+ {
+ // Creates the response.
+ if ($is_authorized && $this->request->idSelect() && $user) {
+ $response = $this->request->answer(
+ $is_authorized, null, $user->login(), $this->GetUserUrl($user));
+ } else {
+ $response = $this->request->answer($is_authorized);
+ }
+
+ // Clobbers response, and get it back to the Relaying Party.
+ if ($sreg_data) {
+ $sreg_data->toMessage($response->fields);
+ }
+ $this->RenderResponse($response);
+ }
+
+ // Automatically handles the request without any user interaction.
+ public function HandleRequest()
+ {
+ $response = $this->server->handleRequest($this->request);
+ $this->RenderResponse($response);
+ }
+
+ // Trust management helpers ------------------------------------------------
+
+ // Returns true iff the current endpoint is currently trusted by |user|.
+ public function IsEndpointTrusted(User $user)
+ {
+ $res = XDB::query(
+ "SELECT COUNT(*)
+ FROM openid_trusted
+ WHERE (user_id = {?} OR user_id IS NULL) AND url = {?}",
+ $user->id(), $this->request->trust_root);
+ return ($res->fetchOneCell() > 0);
+ }
+
+ // Updates the trust level for the given endpoint, based on the value pf
+ // |trusted| and |permanent_trust| (the latter is ignored when the former
+ // value is false). Returns true iff the current endpoint is trusted.
+ public function UpdateEndpointTrust(User &$user, $trusted, $permanent_trust) {
+ $initial_trust = $this->IsEndpointTrusted($user);
+ if (!$initial_trust && $trusted && $permanent_trust) {
+ XDB::execute(
+ "INSERT IGNORE INTO openid_trusted
+ SET user_id = {?}, url = {?}",
+ $user->id(), $this->request->trust_root);
+ }
+
+ return ($initial_trust || $trusted);
+ }
+
+ // Page renderers ----------------------------------------------------------
+
+ // Renders the OpenId discovery page for |user|.
+ public function RenderDiscoveryPage(&$page, User &$user)
+ {
+ $page->changeTpl('openid/openid.tpl');
+ $page->setTitle($user->fullName());
+ $page->addLink('openid.server openid2.provider', $this->base_url);
+ $page->addLink('openid.delegate openid2.local_id', $user->login());
+ $page->assign_by_ref('user', $user);
+
+ // Include the X-XRDS-Location header for Yadis discovery.
+ header('X-XRDS-Location: ' . $this->GetUserXrdsUrl($user));
+ }
+
+ // Renders the main XRDS page.
+ public function RenderMainXrdsPage(&$page)
+ {
+ header('Content-type: application/xrds+xml');
+ $page->changeTpl('openid/idp_xrds.tpl', NO_SKIN);
+ $page->assign('type2', Auth_OpenID_TYPE_2_0_IDP);
+ $page->assign('sreg', Auth_OpenID_SREG_URI);
+ $page->assign('provider', $this->base_url);
+ }
+
+ // Renders the XRDS page of |user|.
+ public function RenderUserXrdsPage(&$page, User &$user)
+ {
+ header('Content-type: application/xrds+xml');
+ $page->changeTpl('openid/user_xrds.tpl', NO_SKIN);
+ $page->assign('type2', Auth_OpenID_TYPE_2_0);
+ $page->assign('type1', Auth_OpenID_TYPE_1_1);
+ $page->assign('sreg', Auth_OpenID_SREG_URI);
+ $page->assign('provider', $this->base_url);
+ $page->assign('local_id', $user->login());
+ }
+
+ // Renders the OpenId response for the HTTP client.
+ public function RenderResponse($response)
+ {
+ if ($response) {
+ $web_response = $this->server->encodeResponse($response);
+ header(sprintf('%s %d', $_SERVER['SERVER_PROTOCOL'], $web_response->code),
+ true, $web_response->code);
+
+ foreach ($web_response->headers as $key => $value) {
+ header(sprintf('%s: %s', $key, $value));
+ }
+
+ header('Connection: close');
+ print $web_response->body;
+ }
+ exit;
+ }
+
+ // URL providers -----------------------------------------------------------
+
+ // Returns the OpenId identity URL of the requested user.
+ private function GetUserUrl(User &$user)
+ {
+ return $this->base_url . '/' . $user->login();
+ }
+
+ // Returns the private XRDS page of a user.
+ private function GetUserXrdsUrl(User &$user)
+ {
+ return $this->base_url . '/xrds/' . $user->login();
+ }
+
+ // Returns the endpoint in the current request.
+ public function GetEndpoint()
+ {
+ return $this->request->trust_root;
+ }
+
+ // Extracts the OpenId arguments available in the current request, and
+ // builds a query string with them.
+ public function GetQueryStringForRequest()
+ {
+ foreach (Auth_OpenID::getQuery() as $key => $value) {
+ if (strpos($key, 'openid.') === 0) {
+ $args[$key] = $value;
+ }
+ }
+
+ return http_build_query($args);
+ }
}
// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
function handlers()
{
return array(
- 'payment' => $this->make_hook('payment', AUTH_MDP),
- 'payment/cyber_return' => $this->make_hook('cyber_return', AUTH_PUBLIC, 'user', NO_HTTPS),
- 'payment/paypal_return' => $this->make_hook('paypal_return', AUTH_PUBLIC, 'user', NO_HTTPS),
- '%grp/paiement' => $this->make_hook('xnet_payment', AUTH_MDP),
- '%grp/payment' => $this->make_hook('xnet_payment', AUTH_MDP),
- '%grp/payment/cyber_return' => $this->make_hook('cyber_return', AUTH_PUBLIC, 'user', NO_HTTPS),
+ 'payment' => $this->make_hook('payment', AUTH_MDP),
+ 'payment/cyber_return' => $this->make_hook('cyber_return', AUTH_PUBLIC, 'user', NO_HTTPS),
+ 'payment/paypal_return' => $this->make_hook('paypal_return', AUTH_PUBLIC, 'user', NO_HTTPS),
+ '%grp/paiement' => $this->make_hook('xnet_payment', AUTH_MDP),
+ '%grp/payment' => $this->make_hook('xnet_payment', AUTH_MDP),
+ '%grp/payment/cyber_return' => $this->make_hook('cyber_return', AUTH_PUBLIC, 'user', NO_HTTPS),
'%grp/payment/paypal_return' => $this->make_hook('paypal_return', AUTH_PUBLIC, 'user', NO_HTTPS),
- 'admin/payments' => $this->make_hook('admin', AUTH_MDP, 'admin'),
+ 'admin/payments' => $this->make_hook('admin', AUTH_MDP, 'admin'),
);
}
$champ901, $user->id(), $ref, $champ200, $montant, $champ905, Env::v('comment'));
/* on genere le mail de confirmation */
- $conf_text = str_replace(array('<prenom>', '<nom>', '<promo>', '<montant>', '<salutation>', '<cher>'),
- array($user->firstName(), $user->lastName(), $user->promo(), $montant,
- $user->isFemale() ? 'Chère' : 'Cher',
- $user->isFemale() ? 'Chère' : 'Cher'), $conf_text);
+ $conf_text = str_replace(
+ array('<prenom>', '<nom>', '<promo>', '<montant>', '<salutation>', '<cher>', 'comment>'),
+ array($user->firstName(), $user->lastName(), $user->promo(), $montant,
+ $user->isFemale() ? 'Chère' : 'Cher', $user->isFemale() ? 'Chère' : 'Cher',
+ Env::v('comment')), $conf_text);
global $globals;
$mymail = new PlMailer();
function handlers()
{
return array(
- 'index' => $this->make_hook('index', AUTH_PUBLIC),
- 'cacert.pem' => $this->make_hook('cacert', AUTH_PUBLIC),
- 'changelog' => $this->make_hook('changelog', AUTH_PUBLIC),
+ 'index' => $this->make_hook('index', AUTH_PUBLIC),
+ 'cacert.pem' => $this->make_hook('cacert', AUTH_PUBLIC),
+ 'changelog' => $this->make_hook('changelog', AUTH_PUBLIC),
// Preferences thingies
- 'prefs' => $this->make_hook('prefs', AUTH_COOKIE),
- 'prefs/rss' => $this->make_hook('prefs_rss', AUTH_COOKIE),
- 'prefs/webredirect'
- => $this->make_hook('webredir', AUTH_MDP),
- 'prefs/skin' => $this->make_hook('skin', AUTH_COOKIE),
+ 'prefs' => $this->make_hook('prefs', AUTH_COOKIE),
+ 'prefs/rss' => $this->make_hook('prefs_rss', AUTH_COOKIE),
+ 'prefs/webredirect' => $this->make_hook('webredir', AUTH_MDP),
+ 'prefs/skin' => $this->make_hook('skin', AUTH_COOKIE),
// password related thingies
- 'password' => $this->make_hook('password', AUTH_MDP),
- 'tmpPWD' => $this->make_hook('tmpPWD', AUTH_PUBLIC),
- 'password/smtp' => $this->make_hook('smtppass', AUTH_MDP),
- 'recovery' => $this->make_hook('recovery', AUTH_PUBLIC),
- 'exit' => $this->make_hook('exit', AUTH_PUBLIC),
- 'review' => $this->make_hook('review', AUTH_PUBLIC),
- 'deconnexion.php' => $this->make_hook('exit', AUTH_PUBLIC),
+ 'password' => $this->make_hook('password', AUTH_MDP),
+ 'tmpPWD' => $this->make_hook('tmpPWD', AUTH_PUBLIC),
+ 'password/smtp' => $this->make_hook('smtppass', AUTH_MDP),
+ 'recovery' => $this->make_hook('recovery', AUTH_PUBLIC),
+ 'exit' => $this->make_hook('exit', AUTH_PUBLIC),
+ 'review' => $this->make_hook('review', AUTH_PUBLIC),
+ 'deconnexion.php' => $this->make_hook('exit', AUTH_PUBLIC),
);
}
{
// Include X-XRDS-Location response-header for Yadis discovery
global $globals;
- header('X-XRDS-Location: ' . $globals->baseurl . '/openid/idp_xrds');
+ header('X-XRDS-Location: ' . $globals->baseurl . '/openid/xrds');
// Redirect to the suitable page
if (S::logged()) {
{
// Include X-XRDS-Location response-header for Yadis discovery
global $globals;
- header('X-XRDS-Location: ' . $globals->baseurl . '/openid/idp_xrds');
+ header('X-XRDS-Location: ' . $globals->baseurl . '/openid/xrds');
$this->load('review.inc.php');
$dom = 'Review';
{
public function __construct(PlWizard &$wiz) { }
public function template() { return 'platal/review.tpl'; }
- public function process() { }
+ public function process(&$success) { }
+ public function success() { }
public function prepare(PlPage &$page, $id)
{
'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'),
-
);
}
http_redirect("http://www.polytechniciens.com/?page=AX_FICHE_ANCIEN&anc_id=" . $user->ax_id);
}
- function handler_p_edit(&$page, $user = null, $opened_tab = null, $mode = null)
+ function handler_p_edit(&$page, $user = null, $opened_tab = null, $mode = null, $success = null)
{
global $globals;
}
$page->setTitle('Mon Profil');
+ if (isset($success) && $success) {
+ $page->trigSuccess('Ton profil a bien été mis à jour.');
+ }
}
function handler_education_js(&$page)
{
$res = XDB::query("SELECT id, accuracy, text, postalText,
postalCode, localityId, subAdministrativeAreaId, administrativeAreaId,
- countryId, latitude, longitude, pub, comment, updateTime,
+ countryId, latitude, longitude, pub, comment, UNIX_TIMESTAMP(updateTime) AS updateTime,
north, south, east, west,
FIND_IN_SET('current', flags) AS current,
FIND_IN_SET('temporary', flags) AS temporary,
}
foreach ($this->values['addresses'] as $id => &$address) {
if (!isset($address['tel'])) {
- $address['tel'] = array();
+ $address['tel'] = array(
+ 0 => array(
+ 'type' => 'fixed',
+ 'tel' => '',
+ 'pub' => 'private',
+ 'comment' => '',
+ )
+ );
}
unset($address['id']);
+ $address['changed'] = 0;
+ $address['removed'] = 0;
}
}
}
{
$success = true;
$success_tmp = true;
+
if (is_null($value)) {
$sn_all = XDB::iterator("SELECT CONCAT(sn.particle, sn.name) AS name,
sn.particle, sn.typeid, e.type, e.name AS type_name,
$sn = $sn_all->next();
}
} else {
- $value[] = array('typeid' => $sn_type['id'],
- 'type' => $sn_type['type'],
- 'type_name' => $sn_type['name'],
- 'pub' => 1,
+ $value[] = array('name' => '',
+ 'particle' => '',
+ 'typeid' => $sn_type['id'],
+ 'type' => $sn_type['type'],
+ 'type_name' => $sn_type['name'],
'has_particle' => $sn_type['has_particle'],
- 'always_displayed' => 1);
+ 'always_displayed' => 1,
+ 'pub' => 1);
}
}
if ($sn) {
Platal::page()->assign('public_name', $public_name);
Platal::page()->assign('private_name', $private_name);
}
+
return $value;
}
if ($has_new) {
$new_names = new NamesReq(S::user(), $this->search_names, $this->private_name_end);
$new_names->submit();
- Platal::page()->trigWarning("La demande de modification de tes noms a bien été prises en compte." .
+ Platal::page()->trigWarning("La demande de modification de tes noms a bien été prise en compte." .
" Tu recevras un email dès que ces changements auront été effectués.");
} else {
$display_names = array();
= $this->settings['yourself']
= $this->settings['promo']
= null;
- $this->settings['synchro_ax']
- = new ProfileBool();
$this->settings['email_directory']
= new ProfileEmail();
$this->settings['email_directory_new']
pr.nationality1, pr.nationality2, pr.nationality3, pr.birthdate,
t.display_tel as mobile, t.pub as mobile_pub,
d.email_directory as email_directory,
- pr.freetext, pr.freetext_pub as freetext_pub
+ pr.freetext, pr.freetext_pub, pr.ax_id AS matricule_ax, p.yourself
FROM profiles AS pr
INNER JOIN profile_display AS p ON (p.pid = pr.pid)
INNER JOIN profile_education AS e ON (e.uid = pr.pid AND FIND_IN_SET('primary', e.flags))
XDB::execute("UPDATE profiles
SET nationality1 = {?}, nationality2 = {?}, nationality3 = {?}, birthdate = {?},
freetext = {?}, freetext_pub = {?}
- WHERE user_id = {?}",
+ WHERE pid = {?}",
$this->values['nationality1'], $this->values['nationality2'], $this->values['nationality3'],
preg_replace('@(\d{2})/(\d{2})/(\d{4})@', '\3-\2-\1', $this->values['birthdate']),
- $this->values['freetext'], $this->values['freetext_pub'],
- $this->pid());
+ $this->values['freetext'], $this->values['freetext_pub'], $this->pid());
}
if ($this->changed['email_directory']) {
$new_email = ($this->values['email_directory'] == "new@example.org") ?
);
}
+ public function emptyJob()
+ {
+ return array(
+ 'id' => '0',
+ 'jobid' => '',
+ 'pub' => 'private',
+ 'name' => '',
+ 'hq_acronym' => '',
+ 'hq_url' => '',
+ 'hq_email' => '',
+ 'hq_address' => array(
+ 'text' => '',
+ 'accuracy' => '',
+ 'postalText' => '',
+ 'postalCode' => '',
+ 'administrativeAreaId' => '',
+ 'subAdministrativeAreaId' => '',
+ 'localityId' => '',
+ 'countryId' => '',
+ 'latitude' => '',
+ 'longitude' => '',
+ 'north' => '',
+ 'south' => '',
+ 'east' => '',
+ 'west' => '',
+ 'cedex' => '',
+ 'updateTime' => '',
+ 'changed' => '0',
+ 'removed' => '0',
+ ),
+ 'hq_phone' => '',
+ 'hq_fax' => '',
+ 'subSubSectorName' => null,
+ 'sector' => '0',
+ 'subSector' => '0',
+ 'subSubSector' => '0',
+ 'description' => '',
+ 'w_url' => '',
+ 'w_address' => array(
+ 'pub' => 'private',
+ 'text' => '',
+ 'accuracy' => '',
+ 'postalText' => '',
+ 'postalCode' => '',
+ 'administrativeAreaId' => '',
+ 'subAdministrativeAreaId' => '',
+ 'localityId' => '',
+ 'countryId' => '',
+ 'latitude' => '',
+ 'longitude' => '',
+ 'north' => '',
+ 'south' => '',
+ 'east' => '',
+ 'west' => '',
+ 'cedex' => '',
+ 'updateTime' => '',
+ 'changed' => '0',
+ 'removed' => '0',
+ ),
+ 'w_email' => '',
+ 'w_email_pub' => 'private',
+ 'w_email_new' => '',
+ 'w_phone' => array(0 => array(
+ 'type' => 'fixed',
+ 'tel' => '',
+ 'pub' => 'private',
+ 'comment' => '',
+ )),
+ );
+ }
+
private function cleanJob(ProfilePage &$page, $jobid, array &$job, &$success)
{
$success = true;
}
$profiletel = new ProfilePhones('pro', $jobid);
$job['w_phone'] = $profiletel->value($page, 'tel', $job['w_phone'], $s);
+
unset($job['removed']);
unset($job['new']);
}
$success = true;
foreach ($value as $key=>&$job) {
$job['name'] = trim($job['name']);
- if (!$job['name']) {
+ if (!$job['name'] && $entreprise) {
$job['tmp_name'] = $entreprise[$entr_val]->name;
$entr_val ++;
}
public function save(ProfilePage &$page, $field, $value)
{
+ // TODO: use address and phone classes to update profile_job_enum and profile_phones once they are done.
+
require_once('profil.func.inc.php');
require_once('validations.inc.php');
WHERE uid = {?} AND link_type = 'pro'",
S::i('uid'));
foreach ($value as $id=>&$job) {
- if ($job['jobid']) {
- XDB::execute("INSERT INTO profile_job (uid, id, description, sectorid, subsectorid,
- subsubsectorid, email, url, pub, email_pub, jobid)
- VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})",
- S::i('uid'), $id, $job['description'], $job['sector'], $job['subSector'],
- $job['subSubSector'], $job['w_email'], $job['w_url'], $job['pub'], $job['w_email_pub'], $job['jobid']);
- } else {
- XDB::execute("INSERT INTO profile_job (uid, id, description, sectorid, subsectorid,
- subsubsectorid, email, url, pub, email_pub)
- VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})",
- S::i('uid'), $id, $job['description'], $job['sector'], $job['subSector'],
- $job['subSubSector'], $job['w_email'], $job['w_url'], $job['pub'], $job['w_email_pub']);
+ if (isset($job['name']) && $job['name']) {
+ if (isset($job['jobid']) && $job['jobid']) {
+ XDB::execute("INSERT INTO profile_job (uid, id, description, sectorid, subsectorid,
+ subsubsectorid, email, url, pub, email_pub, jobid)
+ VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})",
+ S::i('uid'), $id, $job['description'], $job['sector'], $job['subSector'],
+ $job['subSubSector'], $job['w_email'], $job['w_url'], $job['pub'], $job['w_email_pub'], $job['jobid']);
+ } else {
+ XDB::execute("INSERT INTO profile_job (uid, id, description, sectorid, subsectorid,
+ subsubsectorid, email, url, pub, email_pub)
+ VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})",
+ S::i('uid'), $id, $job['description'], $job['sector'], $job['subSector'],
+ $job['subSubSector'], $job['w_email'], $job['w_url'], $job['pub'], $job['w_email_pub']);
+ }
+ $address = new ProfileAddress();
+ $address->saveAddress($id, $job['w_address'], 'job');
+ $profiletel = new ProfilePhones('pro', $id);
+ $profiletel->saveTels('tel', $job['w_phone']);
}
- $address = new ProfileAddress();
- $address->saveAddress($id, $job['w_address'], 'job');
- $profiletel = new ProfilePhones('pro', $id);
- $profiletel->saveTels('tel', $job['w_phone']);
}
}
}
ORDER BY j.id",
$this->pid());
$this->values['jobs'] = array();
- while (list($id, $jobid, $name, $sector, $subSector, $subSubSector,
- $subSubSectorName, $description, $w_email, $w_emailPub, $w_url, $pub,
- $hq_acronym, $hq_url, $hq_email,
- $w_accuracy, $w_text, $w_postalText, $w_postalCode, $w_localityId,
- $w_subAdministrativeAreaId, $w_administrativeAreaId, $w_countryId,
- $w_latitude, $w_longitude, $w_pub, $w_updateTime,
- $w_north, $w_south, $w_east, $w_west,
- $hq_accuracy, $hq_text, $hq_postalText, $hq_postalCode, $hq_localityId,
- $hq_subAdministrativeAreaId, $hq_administrativeAreaId, $hq_countryId,
- $hq_latitude, $hq_longitude, $hq_pub, $hq_updateTime,
- $hq_north, $hq_south, $hq_east, $hq_west,
- ) = $res->next()) {
- $this->values['jobs'][] = array('id' => $id,
- 'jobid' => $jobid,
- 'name' => $name,
- 'sector' => $sector,
- 'subSector' => $subSector,
- 'subSubSector' => $subSubSector,
- 'subSubSectorName' => $subSubSectorName,
- 'description' => $description,
- 'pub' => $pub,
- 'w_email' => $w_email,
- 'w_email_pub' => $w_email_pub,
- 'w_url' => $w_url,
- 'hq_acronym' => $hq_acronym,
- 'hq_url' => $hq_url,
- 'hq_email' => $hq_email,
- 'w_address' => array('accuracy' => $w_accuracy,
- 'text' => $w_text,
- 'postalText' => $w_postalText,
- 'postalCode' => $w_postalCode,
- 'localityId' => $w_localityId,
- 'subAdministrativeAreaId' => $w_subAdministrativeAreaId,
- 'administrativeAreaId' => $w_administrativeAreaId,
- 'countryId' => $w_countryId,
- 'latitude' => $w_latitude,
- 'longitude' => $w_longitude,
- 'pub' => $w_pub,
- 'updateTime' => $w_update,
- 'north' => $w_north,
- 'south' => $w_south,
- 'east' => $w_east,
- 'west' => $w_west,
- ),
- 'hq_address' => array('accuracy' => $hq_accuracy,
- 'text' => $hq_text,
- 'postalText' => $hq_postalText,
- 'postalCode' => $hq_postalCode,
- 'localityId' => $hq_localityId,
- 'subAdministrativeAreaId' => $hq_subAdministrativeAreaId,
- 'administrativeAreaId' => $hq_administrativeAreaId,
- 'countryId' => $hq_countryId,
- 'latitude' => $hq_latitude,
- 'longitude' => $hq_longitude,
- 'pub' => $hq_pub,
- 'updateTime' => $hq_update,
- 'north' => $hq_north,
- 'south' => $hq_south,
- 'east' => $hq_east,
- 'west' => $hq_west,
- ),
- );
- }
- $res = XDB::iterator("SELECT link_id AS jobid, tel_type AS type, pub, display_tel AS tel, comment
- FROM profile_phones
- WHERE uid = {?} AND link_type = 'pro'
- ORDER BY link_id",
- $this->pid());
- $i = 0;
- $jobNb = count($this->values['jobs']);
- while ($phone = $res->next()) {
- $jobid = $phone['jobid'];
- while ($i < $jobNb && $this->values['jobs'][$i]['id'] < $jobid) {
- $i++;
+ if ($res->numRows() > 0) {
+ while (list($id, $jobid, $name, $sector, $subSector, $subSubSector,
+ $subSubSectorName, $description, $w_email, $w_emailPub, $w_url, $pub,
+ $hq_acronym, $hq_url, $hq_email,
+ $w_accuracy, $w_text, $w_postalText, $w_postalCode, $w_localityId,
+ $w_subAdministrativeAreaId, $w_administrativeAreaId, $w_countryId,
+ $w_latitude, $w_longitude, $w_pub, $w_updateTime,
+ $w_north, $w_south, $w_east, $w_west,
+ $hq_accuracy, $hq_text, $hq_postalText, $hq_postalCode, $hq_localityId,
+ $hq_subAdministrativeAreaId, $hq_administrativeAreaId, $hq_countryId,
+ $hq_latitude, $hq_longitude, $hq_pub, $hq_updateTime,
+ $hq_north, $hq_south, $hq_east, $hq_west,
+ ) = $res->next()) {
+ $this->values['jobs'][] = array(
+ 'id' => $id,
+ 'jobid' => $jobid,
+ 'name' => $name,
+ 'sector' => $sector,
+ 'subSector' => $subSector,
+ 'subSubSector' => $subSubSector,
+ 'subSubSectorName' => $subSubSectorName,
+ 'description' => $description,
+ 'pub' => $pub,
+ 'w_email' => $w_email,
+ 'w_email_pub' => $w_emailPub,
+ 'w_url' => $w_url,
+ 'hq_acronym' => $hq_acronym,
+ 'hq_url' => $hq_url,
+ 'hq_email' => $hq_email,
+ 'w_address' => array(
+ 'accuracy' => $w_accuracy,
+ 'text' => $w_text,
+ 'postalText' => $w_postalText,
+ 'postalCode' => $w_postalCode,
+ 'localityId' => $w_localityId,
+ 'subAdministrativeAreaId' => $w_subAdministrativeAreaId,
+ 'administrativeAreaId' => $w_administrativeAreaId,
+ 'countryId' => $w_countryId,
+ 'latitude' => $w_latitude,
+ 'longitude' => $w_longitude,
+ 'pub' => $w_pub,
+ 'updateTime' => $w_updateTime,
+ 'north' => $w_north,
+ 'south' => $w_south,
+ 'east' => $w_east,
+ 'west' => $w_west,
+ ),
+ 'hq_address' => array(
+ 'accuracy' => $hq_accuracy,
+ 'text' => $hq_text,
+ 'postalText' => $hq_postalText,
+ 'postalCode' => $hq_postalCode,
+ 'localityId' => $hq_localityId,
+ 'subAdministrativeAreaId' => $hq_subAdministrativeAreaId,
+ 'administrativeAreaId' => $hq_administrativeAreaId,
+ 'countryId' => $hq_countryId,
+ 'latitude' => $hq_latitude,
+ 'longitude' => $hq_longitude,
+ 'pub' => $hq_pub,
+ 'updateTime' => $hq_updateTime,
+ 'north' => $hq_north,
+ 'south' => $hq_south,
+ 'east' => $hq_east,
+ 'west' => $hq_west,
+ ),
+ );
+ }
+
+ $res = XDB::iterator("SELECT link_id AS jobid, tel_type AS type, pub, display_tel AS tel, comment
+ FROM profile_phones
+ WHERE uid = {?} AND link_type = 'pro'
+ ORDER BY link_id",
+ S::i('uid'));
+ $i = 0;
+ $jobNb = count($this->values['jobs']);
+ while ($phone = $res->next()) {
+ $jobid = $phone['jobid'];
+ while ($i < $jobNb && $this->values['jobs'][$i]['id'] < $jobid) {
+ $i++;
+ }
+ if ($i >= $jobNb) {
+ break;
+ }
+ $job =& $this->values['jobs'][$i];
+ if (!isset($job['w_phone'])) {
+ $job['w_phone'] = array();
+ }
+ if ($job['id'] == $jobid) {
+ $job['w_phone'][] = $phone;
+ }
}
- if ($i >= $jobNb) {
- break;
+ foreach ($this->values['jobs'] as $id => &$job) {
+ if (!isset($job['w_phone'])) {
+ $job['w_phone'] = array(
+ 0 => array(
+ 'type' => 'fixed',
+ 'tel' => '',
+ 'pub' => 'private',
+ 'comment' => '',
+ )
+ );
+ }
}
- $job =& $this->values['jobs'][$i];
- if (!isset($job['w_phone'])) {
- $job['w_phone'] = array();
+
+ $job['w_email_new'] = '';
+ if (!isset($job['hq_phone'])) {
+ $job['hq_phone'] = '';
}
- if ($job['id'] == $jobid) {
- $job['w_phone'][] = $phone;
+ if (!isset($job['hq_fax'])) {
+ $job['hq_fax'] = '';
}
- }
- foreach ($this->values['jobs'] as $id => &$job) {
- if (!isset($job['w_phone'])) {
- $job['w_phone'] = array();
+ if (!isset($job['w_email_pub'])) {
+ $job['w_email_pub'] = 'private';
}
+ if (!$job['hq_address']['text']) {
+ $job['hq_address'] = array(
+ 'text' => '',
+ 'accuracy' => '',
+ 'postalText' => '',
+ 'postalCode' => '',
+ 'administrativeAreaId' => '',
+ 'subAdministrativeAreaId' => '',
+ 'localityId' => '',
+ 'countryId' => '',
+ 'latitude' => '',
+ 'longitude' => '',
+ 'north' => '',
+ 'south' => '',
+ 'east' => '',
+ 'west' => '',
+ 'cedex' => '',
+ 'updateTime' => '',
+ 'changed' => '0',
+ 'removed' => '0',
+ );
+ }
+ $job['w_address']['cedex'] = '';
+ $job['w_address']['changed'] = '0';
+ $job['w_address']['removed'] = '0';
+ } else {
+ $this->values['jobs'][] = $this->settings['jobs']->emptyJob();
}
}
public function value(ProfilePage &$page, $field, $value, &$success)
{
$success = true;
- if (is_null($value) || !is_array($value)) {
+ if (is_null($value)) {
$value = array();
$res = XDB::iterator("SELECT t.display_tel AS tel, t.tel_type AS type, t.pub, t.comment
FROM profile_phones AS t
WHERE t.uid = {?} AND t.link_type = {?}
ORDER BY t.tel_id",
- $page->pid(), $this->link_type);
- $value = $res->fetchAllAssoc();
+ $this->id, $this->link_type);
+ if ($res->numRows() > 0) {
+ $value = $res->fetchAllAssoc();
+ } else {
+ $value = array(
+ 0 => array(
+ 'type' => 'fixed',
+ 'tel' => '',
+ 'pub' => 'private',
+ 'comment' => '',
+ )
+ );
+ }
}
foreach ($value as $key=>&$phone) {
- if (@$phone['removed']) {
+ if (isset($phone['removed']) && $phone['removed']) {
unset($value[$key]);
} else {
unset($phone['removed']);
{
require_once 'geocoding.inc.php';
$success = true;
- if ($address['changed'] == 1) {
+ if (isset($address['changed']) && $address['changed'] == 1) {
$gmapsGeocoder = new GMapsGeocoder();
$address = $gmapsGeocoder->getGeocodedAddress($address);
if (isset($address['geoloc'])) {
$page->assign('errors', $this->errors);
}
- public function process()
+ public function process(&$global_success)
{
$global_success = true;
$this->fetchData();
return Post::has('next_page') ? PlWizard::NEXT_PAGE : PlWizard::CURRENT_PAGE;
}
Platal::page()->trigError("Certains champs n'ont pas pu être validés, merci de corriger les informations "
- . "de ton profil et de revalider ta demande");
+ . "de ton profil et de revalider ta demande.");
return PlWizard::CURRENT_PAGE;
}
+
+ public function success()
+ {
+ return 'Ton profil a bien été mis à jour.';
+ }
}
require_once dirname(__FILE__) . '/general.inc.php';
return array(
'register' => $this->make_hook('register', AUTH_PUBLIC),
'register/end' => $this->make_hook('end', AUTH_PUBLIC),
- 'register/end.php' => $this->make_hook('end_old', AUTH_PUBLIC),
- 'register/success' => $this->make_hook('success', AUTH_MDP),
- 'register/save' => $this->make_hook('save', AUTH_MDP),
);
}
unset($state['backs']);
$sub_state['backs'][] = $state;
if (count($sub_state['backs']) == 3) {
- $alert .= "Tentative d'inscription tres hesitante - ";
+ $alert .= "Tentative d'inscription très hésitante - ";
}
}
- // Compatibility with old sources, keep it atm
- if (!$hash && Env::has('hash')) {
- $hash = Env::v('hash');
- }
-
if ($hash) {
$res = XDB::query(
"SELECT m.uid, u.promo, u.nom, u.prenom, u.matricule, u.naissance_ini, FIND_IN_SET('watch', u.flags)
AND promo = {?}",
$promo);
if (!$res->fetchOneCell()) {
- $err = "La promotion saisie est incorrecte ou tous les camardes de cette promo sont inscrits !";
+ $err = "La promotion saisie est incorrecte ou tous les camarades de cette promotion sont inscrits !";
} else {
$sub_state['step'] = 2;
$sub_state['promo'] = $promo;
case 3:
if (count($_POST)) {
$this->load('register.inc.php');
+
+ // Validate the email address format and domain.
require_once 'emails.inc.php';
if (!isvalid_email(Post::v('email'))) {
- $err[] = "Le champ 'E-mail' n'est pas valide.";
+ $err[] = "Le champ 'Email' n'est pas valide.";
} elseif (!isvalid_email_redirection(Post::v('email'))) {
$err[] = $sub_state['forlife']." doit renvoyer vers un email existant ".
"valide, en particulier, il ne peut pas être renvoyé vers lui-même.";
}
+
+ // Validate the birthday format and range.
$birth = trim(Env::v('naissance'));
if (!preg_match('@^[0-3]?\d/[01]?\d/(19|20)?\d{2}$@', $birth)) {
$err[] = "La 'Date de naissance' n'est pas correcte.";
$promo = (int)$sub_state['promo'];
if ($year > $promo - 15 || $year < $promo - 30) {
$err[] = "La 'Date de naissance' n'est pas correcte.";
- $alert = "Date de naissance incorrecte a l'inscription - ";
+ $alert = "Date de naissance incorrecte à l'inscription - ";
$sub_state['wrong_naissance'] = $birth;
}
}
- // Check if the given email is known as dangerous
+ // Validate the password.
+ if (!Post::v('response2', false)) {
+ $err[] = "Le mot de passe n'est pas valide.";
+ }
+
+ // Check if the given email is known as dangerous.
$res = XDB::query("SELECT w.state, w.description
FROM emails_watch AS w
WHERE w.email = {?} AND w.state != 'safe'",
$email_banned = false;
if ($res->numRows()) {
list($state, $description) = $res->fetchOneRow();
- $alert .= "Email surveille propose a l'inscription - ";
+ $alert .= "Email surveillé proposé à l'inscription - ";
$sub_state['email_desc'] = $description;
if ($state == 'dangerous') {
$email_banned = true;
$alert .= "Inscription d'un utilisateur surveillé - ";
}
- if (check_ip('unsafe')) {
+ if (($ip_banned = check_ip('unsafe'))) {
unset($err);
}
} else {
$sub_state['naissance'] = sprintf("%04d-%02d-%02d",
intval($birth[2]), intval($birth[1]), intval($birth[0]));
+ $sub_state['email'] = Post::v('email');
+ $sub_state['password'] = Post::v('response2');
+
+ // Update the current alert if the birthdate is incorrect,
+ // or if the IP address of the user has been banned.
if ($sub_state['naissance_ini'] != '0000-00-00' && $sub_state['naissance'] != $sub_state['naissance_ini']) {
$alert .= "Date de naissance incorrecte à l'inscription - ";
}
- $sub_state['email'] = Post::v('email');
- $ip_banned = check_ip('unsafe');
if ($ip_banned) {
- $alert .= "Tentative d'inscription depuis une IP surveillee";
+ $alert .= "Tentative d'inscription depuis une IP surveillée";
}
+
+ // Prevent banned user from actually registering; save the current state for others.
if ($email_banned || $ip_banned) {
global $globals;
$err = "Une erreur s'est produite lors de l'inscription."
if (!empty($alert)) {
send_warning_mail($alert);
}
+
$page->changeTpl('register/step'.intval($sub_state['step']).'.tpl');
+ $page->addJsLink('motdepasse.js');
if (isset($err)) {
$page->trigError($err);
}
}
- function handler_end_old(&$page)
- {
- return $this->handler_end($page, Env::v('hash'));
- }
-
function handler_end(&$page, $hash = null)
{
global $globals;
-
-
- $page->changeTpl('register/end.tpl');
$_SESSION['sub_state'] = array('step' => 5);
+ // Reject registration requests from unsafe IP addresses (and remove the
+ // registration information from the database, to prevent IP changes).
if (check_ip('unsafe')) {
send_warning_mail('Une IP surveillée a tenté de finaliser son inscription');
- XDB::execute('DELETE FROM register_pending
- WHERE hash = {?} AND hash != \'INSCRIT\'', $hash);
+ XDB::execute("DELETE FROM register_pending
+ WHERE hash = {?} AND hash != 'INSCRIT'", $hash);
return PL_FORBIDDEN;
}
require_once('user.func.inc.php');
+ // Retrieve the pre-registration information using the url-provided
+ // authentication token.
if ($hash) {
$res = XDB::query(
"SELECT r.uid, r.forlife, r.bestalias, r.mailorg2,
u.promo, FIND_IN_SET('femme', u.flags), u.naissance_ini
FROM register_pending AS r
INNER JOIN auth_user_md5 AS u ON r.uid = u.user_id
- WHERE hash={?} AND hash!='INSCRIT'", $hash);
+ WHERE hash = {?} AND hash != 'INSCRIT'", $hash);
}
-
- if (!$hash || !list($uid, $forlife, $bestalias, $mailorg2, $password, $email,
- $naissance, $nom, $prenom, $promo, $femme, $naiss_ini) = $res->fetchOneRow())
- {
+ if (!$hash || $res->numRows() == 0) {
$page->kill("<p>Cette adresse n'existe pas, ou plus, sur le serveur.</p>
- <p>Causes probables :</p>
+ <p>Causes probables :</p>
<ol>
<li>Vérifie que tu visites l'adresse du dernier
- e-mail reçu s'il y en a eu plusieurs.</li>
+ email reçu s'il y en a eu plusieurs.</li>
<li>Tu as peut-être mal copié l'adresse reçue par
- mail, vérifie-la à la main.</li>
+ email, vérifie-la à la main.</li>
<li>Tu as peut-être attendu trop longtemps pour
confirmer. Les pré-inscriptions sont annulées
tous les 30 jours.</li>
</ol>");
}
+ list($uid, $forlife, $bestalias, $mailorg2, $password, $email,
+ $naissance, $nom, $prenom, $promo, $femme, $naiss_ini) = $res->fetchOneRow();
+ // Prepare the template for display.
+ $page->changeTpl('register/end.tpl');
+ $page->addJsLink('do_challenge_response_logged.js');
+ $page->assign('forlife', $forlife);
+ $page->assign('prenom', $prenom);
+ $page->assign('femme', $femme);
+
+ // Check if the user did enter a valid password; if not (or if none is found),
+ // get her an information page.
+ if (Env::has('response')) {
+ require_once 'secure_hash.inc.php';
+ $expected_response = hash_encrypt("$forlife:$password:" . S::v('challenge'));
+ if (Env::v('response') != $expected_response) {
+ $page->trigError("Mot de passe invalide.");
+ S::logger($uid)->log('auth_fail', 'bad password (register/end)');
+ return;
+ }
+ } else {
+ return;
+ }
- /***********************************************************/
- /****************** REALLY CREATE ACCOUNT ******************/
- /***********************************************************/
-
- XDB::execute('UPDATE auth_user_md5
- SET password={?}, perms="user",
- date=NOW(), naissance={?}, date_ins = NOW()
- WHERE user_id={?}', $password, $naissance, $uid);
- XDB::execute('REPLACE INTO auth_user_quick (user_id) VALUES ({?})', $uid);
- XDB::execute('INSERT INTO aliases (id,alias,type)
- VALUES ({?}, {?}, "a_vie")', $uid,
- $forlife);
- XDB::execute('INSERT INTO aliases (id,alias,type,flags)
- VALUES ({?}, {?}, "alias", "bestalias")',
- $uid, $bestalias);
+ //
+ // Create the user account.
+ //
+ XDB::execute("UPDATE auth_user_md5
+ SET password = {?}, perms = 'user',
+ date = NOW(), naissance = {?}, date_ins = NOW()
+ WHERE user_id = {?}", $password, $naissance, $uid);
+ XDB::execute("REPLACE INTO auth_user_quick (user_id) VALUES ({?})", $uid);
+ XDB::execute("INSERT INTO aliases (id, alias, type)
+ VALUES ({?}, {?}, 'a_vie')", $uid, $forlife);
+ XDB::execute("INSERT INTO aliases (id, alias, type, flags)
+ VALUES ({?}, {?}, 'alias', 'bestalias')", $uid, $bestalias);
if ($mailorg2) {
- XDB::execute('INSERT INTO aliases (id,alias,type)
- VALUES ({?}, {?}, "alias")', $uid,
- $mailorg2);
+ XDB::execute("INSERT INTO aliases (id, alias, type)
+ VALUES ({?}, {?}, 'alias')", $uid, $mailorg2);
}
+ // Add the registration email address as first and only redirection.
require_once('emails.inc.php');
$user = User::getSilent($uid);
$redirect = new Redirect($user);
$redirect->add_email($email);
- // on cree un objet logger et on log l'inscription
+ // Log the registration in the user session.
S::logger($uid)->log('inscription', $email);
- XDB::execute('UPDATE register_pending SET hash="INSCRIT" WHERE uid={?}', $uid);
-
+ XDB::execute("UPDATE register_pending
+ SET hash = 'INSCRIT'
+ WHERE uid = {?}", $uid);
+ // Congratulate our newly registered user by email.
$mymail = new PlMailer('register/inscription.reussie.tpl');
$mymail->assign('forlife', $forlife);
$mymail->assign('prenom', $prenom);
$mymail->send();
- // Enable search on the user
+ // Index the user, to allow her to appear in searches.
require_once('user.func.inc.php');
user_reindex($uid);
- // Add notification for people looking for this registration
+ // Notify other users which were watching for her arrival.
require_once 'notifs.inc.php';
register_watch_op($uid, WATCH_INSCR);
inscription_notifs_base($uid);
- // Default registration on forums
- $p_for = 'xorg.promo.x' . $promo;
- $cible = array('xorg.general', 'xorg.pa.divers', 'xorg.pa.logements', $p_for);
- foreach ($cible as $val) {
- XDB::execute('INSERT INTO forum_subs (fid,uid)
+ // Forcibly register the new user on default forums.
+ $promo_forum = 'xorg.promo.x' . $promo;
+ $registered_forums = array('xorg.general', 'xorg.pa.divers', 'xorg.pa.logements', $promo_forum);
+ foreach ($registered_forums as $forum) {
+ XDB::execute("INSERT INTO forums.abos (fid,uid)
SELECT fid, {?}
- FROM forum
- WHERE name = {?}', $uid, $val);
- if (XDB::affectedRows() == 0 && $val == $p_for) {
+ FROM forums.list
+ WHERE nom = {?}",
+ $uid, $val);
+
+ // Notify the newsgroup admin of the promotion forum needs be created.
+ if (XDB::affectedRows() == 0 && $forum == $promo_forum) {
$res = XDB::query("SELECT SUM(perms IN ('admin','user') AND deces = 0), COUNT(*)
FROM auth_user_md5
WHERE promo = {?}", $promo);
- list($effau, $effid) = $res->fetchOneRow();
- if (5 * $effau > $effid) { // +
+ list($promo_registered_count, $promo_count) = $res->fetchOneRow();
+ if ($promo_registered_count > 0.2 * $promo_count) {
$mymail = new PlMailer('admin/forums-promo.mail.tpl');
$mymail->assign('promo', $promo);
$mymail->send();
}
}
- // update number of subscribers (perms has changed)
+ // Update the global registration count stats.
$globals->updateNbIns();
- if (!Platal::session()->startWeakSession($uid)) {
- return PL_FORBIDDEN;
- }
+ // Try to start a session (so the user don't have to log in); we will use
+ // the password available in Post:: to authenticate the user.
+ Platal::session()->start(AUTH_MDP);
+
+ //
+ // Update collateral data sources, and inform watchers by email.
+ //
- /***********************************************************/
- /************* envoi d'un mail au démarcheur ***************/
- /***********************************************************/
+ // Email the referrer(s) of this new user.
$res = XDB::iterRow(
"SELECT sa.alias, IF(s.nom_usage,s.nom_usage,s.nom) AS nom,
s.prenom, FIND_IN_SET('femme', s.flags) AS femme,
GROUP_CONCAT(m.email SEPARATOR ', ') AS mails, MAX(m.last) AS dateDernier
FROM register_marketing AS m
- INNER JOIN auth_user_md5 AS s ON ( m.sender = s.user_id )
- INNER JOIN aliases AS sa ON ( sa.id = m.sender
- AND FIND_IN_SET('bestalias', sa.flags) )
+ INNER JOIN auth_user_md5 AS s ON (m.sender = s.user_id)
+ INNER JOIN aliases AS sa ON (sa.id = m.sender
+ AND FIND_IN_SET('bestalias', sa.flags))
WHERE m.uid = {?}
GROUP BY m.sender
ORDER BY dateDernier DESC", $uid);
- XDB::execute("UPDATE register_mstats SET success=NOW() WHERE uid={?}", $uid);
+ XDB::execute("UPDATE register_mstats
+ SET success = NOW()
+ WHERE uid = {?}", $uid);
$market = array();
while (list($salias, $snom, $sprenom, $sfemme, $mails, $dateDernier) = $res->next()) {
. "vient à l'instant de terminer son inscription.\n\n"
. "Merci de ta participation active à la reconnaissance de ce site !!!\n\n"
. "Bien cordialement,\n"
+ . "-- \n"
. "L'équipe Polytechnique.org";
$mymail->setTxtBody(wordwrap($msg, 72));
$mymail->send();
}
- /**** send a mail to X.org administrators ****/
+ // Email the plat/al administrators about the registration.
if ($globals->register->notif) {
$mymail = new PlMailer();
$mymail->setSubject("Inscription de $prenom $nom (X$promo)");
$mymail->send();
}
+ // Remove old pending marketing requests for the new user.
Marketing::clear($uid);
- pl_redirect('register/success');
- $page->assign('uid', $uid);
- }
-
- function handler_success(&$page)
- {
- global $globals;
- $page->changeTpl('register/success.tpl');
- $page->assign('user', S::user());
-
- $_SESSION['sub_state'] = array('step' => 5);
- if (Env::has('response2')) {
- $_SESSION['password'] = $password = Post::v('response2');
-
- XDB::execute('UPDATE auth_user_md5 SET password={?}
- WHERE user_id={?}', $password,
- S::v('uid'));
-
- // If GoogleApps is enabled, and the user did choose to use synchronized passwords,
- // and if the (stupid) user has decided to use /register/success another time,
- // updates the Google Apps password as well.
- if ($globals->mailstorage->googleapps_domain) {
- require_once 'googleapps.inc.php';
- $account = new GoogleAppsAccount(S::user());
- if ($account->active() && $account->sync_password) {
- $account->set_password($password);
- }
- }
-
- S::logger()->log('passwd');
- Platal::session()->setAccessCookie(true);
-
- $page->assign('mdpok', true);
- }
-
- $res = XDB::iterRow("SELECT sub, domain
- FROM register_subs
- WHERE uid = {?} AND type = 'list'
- ORDER BY domain",
- S::i('uid'));
- $current_domain = null;
- $lists = array();
- while (list($sub, $domain) = $res->next()) {
- if ($current_domain != $domain) {
- $current_domain = $domain;
- $client = new MMList(S::v('uid'), S::v('password'), $domain);
- }
- list($details, ) = $client->get_members($sub);
- $lists["$sub@$domain"] = $details;
- }
- $page->assign_by_ref('lists', $lists);
-
- $page->addJsLink('motdepasse.js');
- }
-
- function handler_save(&$page)
- {
- global $globals;
-
- // Finish registration procedure
- if (Post::v('register_from_ax_question')) {
- XDB::execute('UPDATE auth_user_quick
- SET profile_from_ax = 1
- WHERE user_id = {?}',
- S::v('uid'));
- }
- if (Post::v('add_to_nl')) {
- require_once 'newsletter.inc.php';
- NewsLetter::subscribe();
- }
- if (Post::v('add_to_ax')) {
- Platal::load('axletter', 'axletter.inc.php');
- AXLetter::subscribe();
- }
- if (Post::v('add_to_promo')) {
- $r = XDB::query('SELECT id FROM groupex.asso WHERE diminutif = {?}',
- S::v('promo'));
- $asso_id = $r->fetchOneCell();
- XDB::execute('REPLACE INTO groupex.membres (uid,asso_id)
- VALUES ({?}, {?})',
- S::v('uid'), $asso_id);
- $mmlist = new MMList(S::v('uid'), S::v('password'));
- $mmlist->subscribe("promo".S::v('promo'));
- }
- if (Post::v('sub_ml')) {
- $subs = array_keys(Post::v('sub_ml'));
- $current_domain = null;
- foreach ($subs as $list) {
- list($sub, $domain) = explode('@', $list);
- if ($domain != $current_domain) {
- $current_domain = $domain;
- $client = new MMList(S::v('uid'), S::v('password'), $domain);
- }
- $client->subscribe($sub);
- }
- }
- if (Post::v('imap')) {
- require_once 'emails.inc.php';
- $user = S::user();
- $storage = new EmailStorage($user, 'imap');
- $storage->activate();
- }
-
pl_redirect('profile/edit');
}
}
// }}}
// {{{ function check_mat
-function check_mat($promo, $mat, $nom, $prenom, &$ourmat, &$ourid, &$watch, &$naiss)
+function check_mat($promo, $mat, &$nom, &$prenom, &$ourmat, &$ourid, &$watch, &$naiss)
{
if (!preg_match('/^[0-9][0-9][0-9][0-9][0-9][0-9]$/', $mat)) {
return "Le matricule doit comporter 6 chiffres.";
return "erreur dans l'identification. Réessaie, il y a une erreur quelque part !";
}
+ $nom = $_nom;
+ $prenom = $_prenom;
$ourid = $uid;
return true;
}
// }}}
// {{{ function check_old_mat
-function check_old_mat($promo, $mat, $nom, $prenom, &$ourmat, &$ourid, &$watch, &$naiss)
+function check_old_mat($promo, $mat, &$nom, &$prenom, &$ourmat, &$ourid, &$watch, &$naiss)
{
$res = XDB::iterRow(
'SELECT user_id, nom, prenom, matricule, FIND_IN_SET(\'watch\', flags), naissance_ini
WHERE promo={?} AND deces=0 AND perms="pending"', $promo);
while (list($_uid, $_nom, $_prenom, $_mat, $watch, $naiss) = $res->next()) {
if (user_cmp($prenom, $nom, $_prenom, $_nom)) {
+ $nom = $_nom;
+ $prenom = $_prenom;
$ourid = $_uid;
$ourmat = $_mat;
return true;
$mailorg = make_username($prenom, $nom);
$mailorg2 = $mailorg.sprintf(".%02u", ($promo%100));
- $res = XDB::query("SELECT hruid FROM auth_user_md5 WHERE user_id = {?}", $uid);
+ $res = XDB::query("SELECT hruid FROM auth_user_md5 WHERE user_id = {?} AND hruid != ''", $uid);
if ($res->numRows() == 0) {
return "Tu n'as pas d'adresse à vie pré-attribuée.<br />"
. "Envoie un mail à <a href=\"mailto:support@{$globals->mail->domain}</a>\">"
global $globals;
extract($sub_state);
- $pass = rand_pass();
- $pass_encrypted = sha1($pass);
- $hash = rand_url_id(12);
-
- XDB::execute('UPDATE auth_user_md5 SET last_known_email={?} WHERE matricule = {?}', $email, $mat);
-
+ $hash = rand_url_id(12);
+ XDB::execute(
+ "UPDATE auth_user_md5
+ SET last_known_email = {?}
+ WHERE matricule = {?}", $email, $mat);
XDB::execute(
"REPLACE INTO register_pending (uid, forlife, bestalias, mailorg2, password, email, date, relance, naissance, hash)
VALUES ({?}, {?}, {?}, {?}, {?}, {?}, NOW(), 0, {?}, {?})",
- $uid, $forlife, $bestalias, $mailorg2, $pass_encrypted, $email, $naissance, $hash);
+ $uid, $forlife, $bestalias, $mailorg2, $password, $email, $naissance, $hash);
$mymail = new PlMailer('register/inscrire.mail.tpl');
$mymail->assign('mailorg', $bestalias);
$mymail->assign('lemail', $email);
- $mymail->assign('pass', $pass);
$mymail->assign('baseurl', $globals->baseurl);
$mymail->assign('hash', $hash);
$mymail->assign('subj', $bestalias."@" . $globals->mail->domain);
--- /dev/null
+<?php
+/***************************************************************************
+ * Copyright (C) 2003-2009 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 *
+ ***************************************************************************/
+
+class ReminderModule extends PLModule
+{
+ function handlers()
+ {
+ return array(
+ 'ajax/reminder' => $this->make_hook('reminder', AUTH_COOKIE),
+ );
+ }
+
+ function handler_reminder(&$page, $reminder_name = null, $action = null)
+ {
+ require_once 'reminder.inc.php';
+ $user = S::user();
+
+ // If no reminder name was passed, or if we don't know that reminder name,
+ // just drop the request.
+ if (!$reminder_name ||
+ !($reminder = Reminder::GetByName($user, $reminder_name))) {
+ return PL_NOT_FOUND;
+ }
+
+ // Otherwise, the request is dispatched, and a new reminder, if any, is
+ // displayed.
+ $reminder->HandleAction($action);
+
+ $previous_reminder = $reminder->title();
+
+ if (($new_reminder = Reminder::GetCandidateReminder($user))) {
+ $new_reminder->DisplayStandalone($page, $previous_reminder);
+ } else {
+ $reminder->NotifiesAction($page);
+ }
+ }
+}
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
S::logger()->log('search', 'quick=' . $quick);
}
$list = 'profile|prf|fiche|fic|referent|ref|mentor';
- if (S::has_perms()) {
+ if (S::admin()) {
$list .= '|admin|adm|ax';
}
if (preg_match('/^(' . $list . '):([-a-z]+(\.[-a-z]+(\.\d{2,4})?)?)$/', replace_accent($quick), $matches)) {
$s = replace_accent(trim($this->value));
$r = $s = str_replace('*','%',$s);
- if (S::has_perms() && strpos($s, '@') !== false) {
+ if (S::admin() && strpos($s, '@') !== false) {
$this->email = $s;
- } else if (S::has_perms() && preg_match('/[0-9]+\.([0-9]+|%)\.([0-9]+|%)\.([0-9]+|%)/', $s)) {
+ } else if (S::admin() && preg_match('/[0-9]+\.([0-9]+|%)\.([0-9]+|%)\.([0-9]+|%)/', $s)) {
$this->ip = $s;
}
if ($this->email || $this->ip) {
function handlers()
{
return array(
- 'stats' => $this->make_hook('stats', AUTH_COOKIE),
- 'stats/evolution' => $this->make_hook('evolution', AUTH_COOKIE),
- 'stats/graph' => $this->make_hook('graph', AUTH_COOKIE),
- 'stats/graph/evolution'
- => $this->make_hook('graph_evo', AUTH_COOKIE),
- 'stats/promos' => $this->make_hook('promos', AUTH_COOKIE),
- 'stats/profile' => $this->make_hook('profile', AUTH_COOKIE),
-
- 'stats/coupures' => $this->make_hook('coupures', AUTH_PUBLIC),
+ 'stats' => $this->make_hook('stats', AUTH_COOKIE),
+ 'stats/evolution' => $this->make_hook('evolution', AUTH_COOKIE),
+ 'stats/graph' => $this->make_hook('graph', AUTH_COOKIE),
+ 'stats/graph/evolution' => $this->make_hook('graph_evo', AUTH_COOKIE),
+ 'stats/promos' => $this->make_hook('promos', AUTH_COOKIE),
+ 'stats/profile' => $this->make_hook('profile', AUTH_COOKIE),
+
+ 'stats/coupures' => $this->make_hook('coupures', AUTH_PUBLIC),
);
}
function handlers()
{
return array(
- 'survey' => $this->make_hook('index', AUTH_PUBLIC),
- 'survey/vote' => $this->make_hook('vote', AUTH_PUBLIC),
- 'survey/result' => $this->make_hook('result', AUTH_PUBLIC),
- 'survey/edit' => $this->make_hook('edit', AUTH_COOKIE),
- 'survey/ajax' => $this->make_hook('ajax', AUTH_COOKIE),
- 'survey/admin' => $this->make_hook('admin', AUTH_MDP, 'admin'),
- 'survey/admin/edit' => $this->make_hook('adminEdit', AUTH_MDP, 'admin'),
+ 'survey' => $this->make_hook('index', AUTH_PUBLIC),
+ 'survey/vote' => $this->make_hook('vote', AUTH_PUBLIC),
+ 'survey/result' => $this->make_hook('result', AUTH_PUBLIC),
+ 'survey/edit' => $this->make_hook('edit', AUTH_COOKIE),
+ 'survey/ajax' => $this->make_hook('ajax', AUTH_COOKIE),
+ 'survey/admin' => $this->make_hook('admin', AUTH_MDP, 'admin'),
+ 'survey/admin/edit' => $this->make_hook('adminEdit', AUTH_MDP, 'admin'),
'survey/admin/valid' => $this->make_hook('adminValidate', AUTH_MDP, 'admin'),
- 'survey/admin/del' => $this->make_hook('adminDelete', AUTH_MDP, 'admin'),
+ 'survey/admin/del' => $this->make_hook('adminDelete', AUTH_MDP, 'admin'),
);
}
// }}}
function handlers()
{
return array(
- 'index' => $this->make_hook('index', AUTH_PUBLIC),
- 'exit' => $this->make_hook('exit', AUTH_PUBLIC),
-
- 'admin' => $this->make_hook('admin', AUTH_MDP, 'admin'),
- 'groups' => $this->make_hook('groups', AUTH_PUBLIC),
- 'groupes.php' => $this->make_hook('groups2', AUTH_PUBLIC),
- 'plan' => $this->make_hook('plan', AUTH_PUBLIC),
- 'photo' => $this->make_hook('photo', AUTH_MDP),
- 'autologin' => $this->make_hook('autologin', AUTH_MDP),
+ 'index' => $this->make_hook('index', AUTH_PUBLIC),
+ 'exit' => $this->make_hook('exit', AUTH_PUBLIC),
+
+ 'admin' => $this->make_hook('admin', AUTH_MDP, 'admin'),
+ 'groups' => $this->make_hook('groups', AUTH_PUBLIC),
+ 'groupes.php' => $this->make_hook('groups2', AUTH_PUBLIC),
+ 'plan' => $this->make_hook('plan', AUTH_PUBLIC),
+ 'photo' => $this->make_hook('photo', AUTH_MDP),
+ 'autologin' => $this->make_hook('autologin', AUTH_MDP),
);
}
if (Post::has('diminutif')) {
S::assert_xsrf_token();
- XDB::query('INSERT INTO groupex.asso (id,diminutif)
- VALUES(NULL,{?})', Post::v('diminutif'));
- pl_redirect('../'.Post::v('diminutif').'/edit');
+ $res = XDB::query('SELECT COUNT(*)
+ FROM groupex.asso
+ WHERE diminutif = {?}',
+ Post::v('diminutif'));
+
+ if ($res->fetchOneCell() == 0) {
+ XDB::execute('INSERT INTO groupex.asso (id, diminutif)
+ VALUES (NULL, {?})',
+ Post::v('diminutif'));
+ pl_redirect('../' . Post::v('diminutif') . '/edit');
+ } else {
+ $page->trigError('Le diminutif demandé est déjà pris.');
+ }
}
- $res = XDB::query('SELECT nom,diminutif FROM groupex.asso ORDER by NOM');
+ $res = XDB::query('SELECT nom, diminutif
+ FROM groupex.asso
+ ORDER BY nom');
$page->assign('assos', $res->fetchAllAssoc());
}
function handlers()
{
return array(
- '%grp' => $this->make_hook('index', AUTH_PUBLIC),
- '%grp/asso.php' => $this->make_hook('index', AUTH_PUBLIC),
- '%grp/logo' => $this->make_hook('logo', AUTH_PUBLIC),
- '%grp/site' => $this->make_hook('site', AUTH_PUBLIC),
- '%grp/edit' => $this->make_hook('edit', AUTH_MDP, 'groupadmin'),
- '%grp/mail' => $this->make_hook('mail', AUTH_MDP, 'groupadmin'),
- '%grp/forum' => $this->make_hook('forum', AUTH_MDP, 'groupmember'),
- '%grp/annuaire' => $this->make_hook('annuaire', AUTH_MDP, 'groupannu'),
- '%grp/annuaire/vcard' => $this->make_hook('vcard', AUTH_MDP, 'groupmember:groupannu'),
- '%grp/annuaire/csv' => $this->make_hook('csv', AUTH_MDP, 'groupmember:groupannu'),
- '%grp/trombi' => $this->make_hook('trombi', AUTH_MDP, 'groupannu'),
- '%grp/geoloc' => $this->make_hook('geoloc', AUTH_MDP, 'groupannu'),
- '%grp/subscribe' => $this->make_hook('subscribe', AUTH_MDP),
- '%grp/subscribe/valid' => $this->make_hook('subscribe_valid', AUTH_MDP, 'groupadmin'),
- '%grp/unsubscribe' => $this->make_hook('unsubscribe', AUTH_MDP, 'groupmember'),
-
- '%grp/change_rights' => $this->make_hook('change_rights', AUTH_MDP),
-
- '%grp/admin/annuaire'
- => $this->make_hook('admin_annuaire', AUTH_MDP, 'groupadmin'),
-
- '%grp/member'
- => $this->make_hook('admin_member', AUTH_MDP, 'groupadmin'),
- '%grp/member/new'
- => $this->make_hook('admin_member_new', AUTH_MDP, 'groupadmin'),
- '%grp/member/new/ajax'
- => $this->make_hook('admin_member_new_ajax', AUTH_MDP, 'user', NO_AUTH),
- '%grp/member/del'
- => $this->make_hook('admin_member_del', AUTH_MDP, 'groupadmin'),
-
- '%grp/rss' => $this->make_hook('rss', AUTH_PUBLIC, 'user', NO_HTTPS),
- '%grp/announce/new' => $this->make_hook('edit_announce', AUTH_MDP, 'groupadmin'),
- '%grp/announce/edit' => $this->make_hook('edit_announce', AUTH_MDP, 'groupadmin'),
- '%grp/announce/photo' => $this->make_hook('photo_announce', AUTH_PUBLIC),
- '%grp/admin/announces' => $this->make_hook('admin_announce', AUTH_MDP, 'groupadmin'),
+ '%grp' => $this->make_hook('index', AUTH_PUBLIC),
+ '%grp/asso.php' => $this->make_hook('index', AUTH_PUBLIC),
+ '%grp/logo' => $this->make_hook('logo', AUTH_PUBLIC),
+ '%grp/site' => $this->make_hook('site', AUTH_PUBLIC),
+ '%grp/edit' => $this->make_hook('edit', AUTH_MDP, 'groupadmin'),
+ '%grp/mail' => $this->make_hook('mail', AUTH_MDP, 'groupadmin'),
+ '%grp/forum' => $this->make_hook('forum', AUTH_MDP, 'groupmember'),
+ '%grp/annuaire' => $this->make_hook('annuaire', AUTH_MDP, 'groupannu'),
+ '%grp/annuaire/vcard' => $this->make_hook('vcard', AUTH_MDP, 'groupmember:groupannu'),
+ '%grp/annuaire/csv' => $this->make_hook('csv', AUTH_MDP, 'groupmember:groupannu'),
+ '%grp/trombi' => $this->make_hook('trombi', AUTH_MDP, 'groupannu'),
+ '%grp/geoloc' => $this->make_hook('geoloc', AUTH_MDP, 'groupannu'),
+ '%grp/subscribe' => $this->make_hook('subscribe', AUTH_MDP),
+ '%grp/subscribe/valid' => $this->make_hook('subscribe_valid', AUTH_MDP, 'groupadmin'),
+ '%grp/unsubscribe' => $this->make_hook('unsubscribe', AUTH_MDP, 'groupmember'),
+
+ '%grp/change_rights' => $this->make_hook('change_rights', AUTH_MDP),
+ '%grp/admin/annuaire' => $this->make_hook('admin_annuaire', AUTH_MDP, 'groupadmin'),
+ '%grp/member' => $this->make_hook('admin_member', AUTH_MDP, 'groupadmin'),
+ '%grp/member/new' => $this->make_hook('admin_member_new', AUTH_MDP, 'groupadmin'),
+ '%grp/member/new/ajax' => $this->make_hook('admin_member_new_ajax', AUTH_MDP, 'user', NO_AUTH),
+ '%grp/member/del' => $this->make_hook('admin_member_del', AUTH_MDP, 'groupadmin'),
+
+ '%grp/rss' => $this->make_hook('rss', AUTH_PUBLIC, 'user', NO_HTTPS),
+ '%grp/announce/new' => $this->make_hook('edit_announce', AUTH_MDP, 'groupadmin'),
+ '%grp/announce/edit' => $this->make_hook('edit_announce', AUTH_MDP, 'groupadmin'),
+ '%grp/announce/photo' => $this->make_hook('photo_announce', AUTH_PUBLIC),
+ '%grp/admin/announces' => $this->make_hook('admin_announce', AUTH_MDP, 'groupadmin'),
);
}
$site = "";
}
if (S::has_perms()) {
- if (strstr(Post::v('mail_domain'), '.') === false) {
- $page->trigError("le domaine doit être un FQDN (aucune modif effectuée) !!!");
+ if (Post::v('mail_domain') && (strstr(Post::v('mail_domain'), '.') === false)) {
+ $page->trigError("Le domaine doit être un FQDN (aucune modification effectuée) !!!");
return;
}
XDB::execute(
XDB::execute(
"UPDATE groupex.asso
SET descr={?}, site={?}, mail={?}, resp={?},
- forum={?}, ax={?}, pub= {?}, sub_url={?},
+ forum={?}, pub= {?}, sub_url={?},
unsub_url={?},flags={?}
WHERE id={?}",
Post::v('descr'), $site,
Post::v('mail'), Post::v('resp'),
- Post::v('forum'), Post::has('ax'),
- Post::v('pub'),
+ Post::v('forum'), Post::v('pub'),
Post::v('sub_url'), Post::v('unsub_url'),
$flags, $globals->asso('id'));
}
pl_redirect('../'.Post::v('diminutif', $globals->asso('diminutif')).'/edit');
}
- if (S::has_perms()) {
+ if (S::admin()) {
$dom = XDB::iterator('SELECT * FROM groupex.dom ORDER BY nom');
$page->assign('dom', $dom);
$page->assign('super', true);
$this->load('mail.inc.php');
set_time_limit(120);
$tos = get_all_redirects($mbr, $mls, $mmlist);
+
$upload = PlUpload::get($_FILES['uploaded'], S::user()->login(), 'xnet.emails', true);
+ if (!$upload && @$_FILES['uploaded']['name'] && PlUpload::$lastError != null) {
+ $page->trigError(PlUpload::$lastError);
+ return;
+ }
+
send_xnet_mails($from, $sujet, $body, Env::v('wiki'), $tos, Post::v('replyto'), $upload, @$_FILES['uploaded']['name']);
if ($upload) {
$upload->rm();
$mailer->setSubject('['.$globals->asso('nom').'] Demande d\'inscription annulée');
$mailer->setTxtBody(Env::v('motif'));
$mailer->send();
- $page->kill("La demande de {$user->fullName()} a bien été refusée.");
+ $page->killSuccess("La demande de {$user->fullName()} a bien été refusée.");
} else {
$page->assign('show_form', true);
$page->assign('reason', $reason);
. "à l'adresse : support@polytechnique.org\n";
if (!$to) {
- $to = $globals->asso("mail").", support@polytechnique.org";
+ $to = ($globals->asso('mail') != '') ? $globals->asso('mail') . ', ' : '';
+ $to .= 'support@polytechnique.org';
$append = "\n-- \nLe groupe ".$globals->asso("nom")
." n'a pas d'administrateur, l'équipe de"
." Polytechnique.org a été prévenue et va rapidement"
function handlers()
{
return array(
- '%grp/lists' => $this->make_hook('lists', AUTH_MDP, 'groupmember'),
- '%grp/lists/create' => $this->make_hook('create', AUTH_MDP, 'groupmember'),
+ '%grp/lists' => $this->make_hook('lists', AUTH_MDP, 'groupmember'),
+ '%grp/lists/create' => $this->make_hook('create', AUTH_MDP, 'groupmember'),
- '%grp/lists/members' => $this->make_hook('members', AUTH_COOKIE),
- '%grp/lists/csv' => $this->make_hook('csv', AUTH_COOKIE),
- '%grp/lists/annu' => $this->make_hook('annu', AUTH_COOKIE),
- '%grp/lists/archives' => $this->make_hook('archives', AUTH_COOKIE),
- '%grp/lists/archives/rss' => $this->make_hook('rss', AUTH_PUBLIC),
+ '%grp/lists/members' => $this->make_hook('members', AUTH_COOKIE),
+ '%grp/lists/csv' => $this->make_hook('csv', AUTH_COOKIE),
+ '%grp/lists/annu' => $this->make_hook('annu', AUTH_COOKIE),
+ '%grp/lists/archives' => $this->make_hook('archives', AUTH_COOKIE),
+ '%grp/lists/archives/rss' => $this->make_hook('rss', AUTH_PUBLIC),
- '%grp/lists/moderate' => $this->make_hook('moderate', AUTH_MDP),
- '%grp/lists/admin' => $this->make_hook('admin', AUTH_MDP),
- '%grp/lists/options' => $this->make_hook('options', AUTH_MDP),
- '%grp/lists/delete' => $this->make_hook('delete', AUTH_MDP),
+ '%grp/lists/moderate' => $this->make_hook('moderate', AUTH_MDP),
+ '%grp/lists/admin' => $this->make_hook('admin', AUTH_MDP),
+ '%grp/lists/options' => $this->make_hook('options', AUTH_MDP),
+ '%grp/lists/delete' => $this->make_hook('delete', AUTH_MDP),
- '%grp/lists/soptions' => $this->make_hook('soptions', AUTH_MDP),
- '%grp/lists/check' => $this->make_hook('check', AUTH_MDP),
- '%grp/lists/sync' => $this->make_hook('sync', AUTH_MDP),
+ '%grp/lists/soptions' => $this->make_hook('soptions', AUTH_MDP),
+ '%grp/lists/check' => $this->make_hook('check', AUTH_MDP),
+ '%grp/lists/sync' => $this->make_hook('sync', AUTH_MDP),
- '%grp/alias/admin' => $this->make_hook('aadmin', AUTH_MDP, 'groupadmin'),
- '%grp/alias/create' => $this->make_hook('acreate', AUTH_MDP, 'groupadmin'),
+ '%grp/alias/admin' => $this->make_hook('aadmin', AUTH_MDP, 'groupadmin'),
+ '%grp/alias/create' => $this->make_hook('acreate', AUTH_MDP, 'groupadmin'),
/* hack: lists uses that */
- 'profile' => $this->make_hook('profile', AUTH_PUBLIC),
+ 'profile' => $this->make_hook('profile', AUTH_PUBLIC),
);
}
}
$listes = $this->client->get_lists();
- $page->assign('listes',$listes);
+ $page->assign('listes', $listes);
$alias = XDB::iterator(
'SELECT alias,type
$page->assign('alias', $alias);
$page->assign('may_update', may_update());
+
+ if (count($listes) > 0 && !$globals->asso('has_ml')) {
+ XDB::execute("UPDATE groupex.asso
+ SET flags = CONCAT_WS(',', IF(flags = '', NULL, flags), 'has_ml')
+ WHERE id = {?}",
+ $globals->asso('id'));
+ }
}
function handler_create(&$page)
VALUES ({?}, {?})', XDB::insertId(),
$red . $mdir . '@listes.polytechnique.org');
}
+
+ XDB::execute("UPDATE groupex.asso
+ SET flags = CONCAT_WS(',', IF(flags = '', NULL, flags), 'has_ml')
+ WHERE id = {?}",
+ $globals->asso('id'));
+
pl_redirect('lists/admin/'.$liste);
}
$txthtml = "";
if (count($param['tels'])) {
foreach ($param['tels'] as $tel) {
+ $tel_type = ($param['dcd'] ? 'Dernier ' : '');
switch ($tel['tel_type']) {
- case 'fixed':
- $tel_type = 'Tél';
+ case 'fixed':
+ $tel_type .= 'Tél';
break;
- case 'fax':
- $tel_type = 'Fax';
+ case 'fax':
+ $tel_type .= 'Fax';
break;
- case 'mobile':
- $tel_type = 'Mob';
+ case 'mobile':
+ $tel_type .= 'Mob';
break;
- default:
- $tel_type = $tel['tel_type'];
+ default:
+ $tel_type .= $tel['tel_type'];
}
$txthtml .= "<div>\n<em>" . $tel_type . " : </em>\n<strong>" . $tel['tel'] . "</strong>\n";
$comment = "";
}
if (Cookie::v('domain', 'login') != 'alias') {
- $res = XDB::query("SELECT alias FROM aliases
- WHERE id={?} AND (type IN ('a_vie','alias') AND FIND_IN_SET('bestalias', flags))", $id);
- return $res->fetchOneCell();
+ $res = XDB::query("SELECT alias FROM aliases
+ WHERE id={?} AND (type IN ('a_vie','alias') AND FIND_IN_SET('bestalias', flags))", $id);
+ return $res->fetchOneCell();
} else {
- $res = XDB::query("
- SELECT v.alias
- FROM virtual AS v
- INNER JOIN virtual_redirect USING(vid)
- INNER JOIN aliases AS a ON(id={?} AND a.type='a_vie')
- WHERE redirect = CONCAT(a.alias, {?})
- OR redirect = CONCAT(a.alias, {?})",
- $id, "@".$globals->mail->domain, "@".$globals->mail->domain2);
- $alias = $res->fetchOneCell();
- return substr($alias, 0, strpos($alias, "@"));
+ $res = XDB::query("
+ SELECT v.alias
+ FROM virtual AS v
+ INNER JOIN virtual_redirect USING(vid)
+ INNER JOIN aliases AS a ON(id={?} AND a.type='a_vie')
+ WHERE redirect = CONCAT(a.alias, {?})
+ OR redirect = CONCAT(a.alias, {?})",
+ $id, "@".$globals->mail->domain, "@".$globals->mail->domain2);
+ $alias = $res->fetchOneCell();
+ return substr($alias, 0, strpos($alias, "@"));
}
return $login;
<form action="admin/deaths" method="post">
- <table class="tinybicol">
+ <table class="bicol">
<tr>
<td>
Promotion :
<td>{$selectedJob.holdingAcronym}</td>
</tr>
<tr>
+ <td>Adresse</td>
+ <td<textarea cols="30" rows="4" name="address">{$selectedJob.address}</textarea></td>
+ </tr>
+ <tr>
+ <td>Téléphone</td>
+ <td><input type="text" name="tel" value="{$selectedJob.tel}" /></td>
+ </tr>
+ <tr>
+ <td>Fax</td>
+ <td><input type="text" name="fax" value="{$selectedJob.fax}" /></td>
+ </tr>
+ <tr>
<td>Remplacer par l'entreprise n°</td>
<td><input type="text" name="newJobId" /></td>
</tr>
{xsrf_token_field}
<div class="center">
<input type="hidden" name="user_id" value="{$smarty.request.user_id}" />
- Confirmer la suppression de {$smarty.request.user_id}
+ Confirmer la suppression de l'utilisateur {$smarty.request.user_id} ({$mr.prenom} {$mr.nom} - X{$mr.promo})
<input type="submit" name="u_kill" value="continuer" />
</div>
</form>
</td>
</tr>
{include file="include/field.promo.tpl" prefix=""}
+ <tr>
+ <td class="titre">Envoyer à une liste d'adresses</td>
+ <td><textarea name="subset_to" rows="7" cols="78">{$subset_to}</textarea><br />
+ <span class="smaller">Indiquez une liste d'adresses emails : la lettre sera envoyée uniquement aux personnes des promotions sélectionnées, dont l'adresse figure dans la liste, et qui souhaitent recevoir les emails de l'AX.</span>
+ </td>
+ </tr>
{if !$saved}
<tr>
<td class="titre">Echéance d'envoi</td>
<input type="text" name="username" size="20" maxlength="50" value="{insert name="getUserName"}" /> @ <select name="domain">
<option value="login">{#globals.mail.domain#} / {#globals.mail.domain2#}</option>
<option value="alias" {if $smarty.cookies.ORGdomain eq alias}selected="selected"{/if}>
- {#globals.mail.alias_dom#} / {#globals.mail.alias_dom2#}
+ {#globals.mail.alias_dom#} / {#globals.mail.alias_dom2#}
</option>
- {$smarty.cookies.domain}
</select>
</td>
</tr>
<div>
{xsrf_token_field}
<input type="hidden" name="challenge" value="{$smarty.session.challenge}" />
- <input type="hidden" name="username" value="{$smarty.cookies.ORGuid}" />
- <input type="hidden" name="xorpass" value="" />
+ <input type="hidden" name="username" value="{$smarty.session.uid}" />
<input type="hidden" name="remember" value="" />
<input type="hidden" name="response" value="" />
</div>
correspondant si tu veux que nous puissions te répondre.
</p>
{elseif $x && $x.nb_mails}
-<h2>Patte Cassée</h2>
+<h2>Patte cassée</h2>
<p>
Ton correspondant a à l'heure actuelle <span class="erreur">{$x.nb_mails} adresse(s) email(s) de redirection active(s)
en dehors de celle que tu nous as communiquée</span>. Cela ne veut pas forcément dire qu'il les avait
<a href="emails/broken/warn/{$email}?token={xsrf_token}">clique sur ce lien</a>.
</p>
{elseif $x}
-<h2>Patte Cassée</h2>
+<h2>Patte cassée</h2>
<p>
Désolé, mais ton correspondant, {$x.user->fullName()},
n'a actuellement <span class="erreur">aucune adresse email de redirection
return function() {
if (!allow) {
if (box.value != '') {
- alert("Un mail de validation vient d'être envoyer sur " + mail
+ alert("Un mail de validation vient d'être envoyé sur " + mail
+ ". La réécriture ne sera active que lorsque tu auras cliqué sur le lien indiqué dans ce mail.");
}
}
</table>
<script type="text/javascript">showRemove(); activeEnable();</script>
</div>
+<p class="smaller center">
+ Légende : {icon name=cross title="Supprimer"} Supprimer la redirection
+ - {icon name=information title="Plus d'informations"} Plus d'informations
+</p>
{if $panne}
<p class="smaller">
<strong>
</div>
{/if}
-{if $smarty.session.no_redirect}
-<div class="errors">
- <ul>
- <li>
- Tu n'as plus de redirection valide ce qui rend ton adresse Polytechnique.org
- inutilisable. Rends-toi au plus vite sur <a href="emails/redirect">la page de
- gestion des emails</a> pour corriger ce problème.
- </li>
- </ul>
-</div>
-{/if}
-
-{if $smarty.session.mx_failures|@count}
-<div class="warnings">
- {icon name=error} Des problèmes sont actuellement recontrés sur tes redirections suivantes :
- <ul>
- {foreach from=$smarty.session.mx_failures item=mail}
- <li>
- <span class="erreur">{$mail.mail}</span> :
- <span class="explication">{$mail.text}</span>
- </li>
- {/foreach}
- </ul>
- <div style="text-align: center"><a href="emails/redirect">Gérer mes adresses de redirection</a></div>
-</div>
-{/if}
-
-{if $fiche_incitation || $photo_incitation || ($geoloc_incitation > 0)}
-<div class="warnings">
- <ul>
-{if $fiche_incitation}
- <li>
- La dernière mise à jour de ta
- <a href="profile/{$smarty.session.hruid}" class="popup2">fiche</a>
- date du {$fiche_incitation|date_format}.
- Il est possible qu'elle ne soit pas à jour.
- Si tu souhaites la modifier, <a href="profile/edit">clique ici !</a>
- </li>
-{/if}
-
-{if $photo_incitation}
- <li>
- Tu n'as pas mis de photo de toi sur ta fiche, c'est dommage.
- Clique <a href="photo/change">ici</a> si tu souhaites en ajouter une.
- </li>
-{/if}
-
-{if $geoloc_incitation > 0}
- <li>
- Parmi tes adresses, il y en a {$geoloc_incitation} que nous n'avons pas pu localiser.
- Clique <a href="profile/edit/adresses">ici</a> pour rectifier.
- </li>
-{/if}
- </ul>
-</div>
+{if $reminder}
+{include file="reminder/base.tpl"}
+{else}
+{include file="include/tips.tpl" full=true}
{/if}
-{include file="include/tips.tpl" full=true}
-
<table class="tinybicol" id="menu-evts">
{foreach from=$events name=events key=category item=evenement}
<tr class="pair" style="height: 18px">
-->
{/literal}
</script>
-
+
{foreach from=$events key=category item=evenement}
{foreach item=ev from=$evenement}
{if $ev.nonlu}
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="css/base.css" media="all"/>
<link rel="stylesheet" type="text/css" href="css/igoogle.css" media="all"/>
- <script type="text/javascript" src="javascript/ajax.js"></script>
- <script type="text/javascript" src="javascript/base.js"></script>
- <script type="text/javascript" src="javascript/igoogle.js"></script>
- <script type="text/javascript" src="javascript/xorg.js"></script>
+ <script type="text/javascript">var platal_baseurl = "{$globals->baseurl}/";</script>
+ {javascript name=jquery}
+ {javascript name=ajax}
+ {javascript name=xorg}
+ {javascript name=igoogle}
{foreach from=$gadget_js item=js}
<script type="text/javascript" src="{$js}"></script>
{/foreach}
- <script type="text/javascript">var platal_baseurl = "{$globals->baseurl}/";</script>
</head>
<body onload="igOnLoadHandler();">
{if $gadget_tpl}{include file=$gadget_tpl}{/if}
<input type="hidden" name="{$prefname}[geocodedPostalText]" value="{$address.geocodedPostalText}" />
<input type="hidden" name="{$prefname}[updateTime]" value="{$address.updateTime}" />
{/if}
-<input type="hidden" name="{$prefname}[type]" value="{$address.type}" />
<input type="hidden" name="{$prefname}[accuracy]" value="{$address.accuracy}" />
-<input type="hidden" name="{$prefname}[postalAddress]" value="{$address.postalAddress}" />
<input type="hidden" name="{$prefname}[postalText]" value="{$address.postalText}" />
-<input type="hidden" name="{$prefname}[line1]" value="{$address.line1}" />
-<input type="hidden" name="{$prefname}[line2]" value="{$address.line2}" />
-<input type="hidden" name="{$prefname}[line3]" value="{$address.line3}" />
<input type="hidden" name="{$prefname}[postalCode]" value="{$address.postalCode}" />
<input type="hidden" name="{$prefname}[administrativeAreaId]" value="{$address.administrativeAreaId}" />
<input type="hidden" name="{$prefname}[subAdministrativeAreaId]" value="{$address.subAdministrativeAreaId}" />
-<input type="hidden" name="{$prefname}[locality]" value="{$address.locality}" />
-<input type="hidden" name="{$prefname}[administrativeArea]" value="{$address.administrativeArea}" />
-<input type="hidden" name="{$prefname}[subAdministrativeArea]" value="{$address.subAdministrativeArea}" />
<input type="hidden" name="{$prefname}[localityId]" value="{$address.localityId}" />
<input type="hidden" name="{$prefname}[countryId]" value="{$address.countryId}" />
<input type="hidden" name="{$prefname}[latitude]" value="{$address.latitude}" />
<tr class="pair">
<td class="titre">Utilisation du quota d'emails</td><td>{$a->r_disk_usage/1024/1024|string_format:"%.2f"}MB</td>
</tr>
+
+ <tr class="impair">
+ <td class="titre">Alias email du compte</td>
+ <td>{foreach from=$a->nicknames() item=nickname}{$nickname}<br />{/foreach}{$a->g_account_name}</td>
+ </tr>
</table><br />
<form action="admin/googleapps/user/{$a->g_account_name}" method="post">
</tr>
<tr class="impair">
- <td colspan="2"><b>Création du compte :</b></td>
+ <td colspan="2"><b>Création du compte :</b></td>
</tr>
<tr class="impair">
<td></td>
- <td>La mise en place du compte Google Apps prends quelques minutes. Tu recevras un email explicatif dès l'opération terminée.</td>
+ <td>La mise en place du compte Google Apps prend quelques minutes. Tu recevras un email explicatif dès l'opération terminée.</td>
</tr>
<tr class="impair">
<td colspan="2" style="text-align:center">
<input type="text" name="NAF_code" size="25" maxlength="200" value="{$valid->NAF_code}" /><br />
<strong>Code AX :</strong>
<input type="text" name="AX_code" size="25" maxlength="200" value="{$valid->AX_code}" /><br />
+<strong>Adresse :</strong>
+<textarea cols="30" rows="4" name="address">{$valid->address}</textarea><br />
<strong>Téléphone :</strong>
<input type="text" name="tel" size="25" maxlength="200" value="{$valid->tel}" /><br />
<strong>Fax :</strong>
<td>{$valid->AX_code}</td>
</tr>
<tr class="pair">
+ <td class="titre">Adresse :</td>
+ <td>{$valid->address}</td>
+</tr>
+<tr class="pair">
<td class="titre">Téléphone :</td>
<td>{$valid->tel}</td>
</tr>
<tr class="impair">
<td class="titre">Promotion :</td>
- <td>{$valid->user->promo()}</td>
+ <td>{$valid->entryYear}</td>
</tr>
<tr class="impair">
<td class="titre">Année de sortie :</td>
- <td>{$valid->promo_sortie} au lieu de {math equation="a + b" a=$valid->user->promo() b=3}</td>
+ <td>{$valid->newGradYear} au lieu de {$valid->oldGradYear}</td>
</tr>
{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
<td class="rt"><a href="{$web}">{$web}</a></td>
</tr>
{/if}
- {if $address.country}
+ {if $address.country && !$c.dcd}
<tr>
<td class="lt">Géographie :</td>
<td class="rt">{if $address.locality}{$address.locality}, {/if}{$address.country}</td>
<p>
Nombre d'<a href="marketing/this_week">inscrits ces 7 derniers jours</a> : {$nbInsSem}<br />
-Nombre d'<a href="marketing/relance">inscriptions en cours</a> (2ème phase non terminée) : {$nbInsEnCours} <br />
-Nombre d'envois marketing effectués n'ayant pas abouti : {$nbInsMarket}<br />
-Nombre d'envois marketing ayant abouti cette semaine : {$nbInsMarkOK}
+Nombre d'<a href="marketing/relance">inscriptions en cours</a> (2ème phase non terminée) : {$nbInsEnCours}
</p>
+<table class="bicol">
+ <tr>
+ <th colspan="4">Marketings</th>
+ </tr>
+ <tr>
+ <td> </td>
+ <td class="titre">Abouti</td>
+ <td class="titre">Non abouti</td>
+ <td class="titre">Total</td>
+ </tr>
+ <tr>
+ <td>Personnel</td>
+ <td>{$nbInsMarketOkPerso}</td>
+ <td>{$nbInsMarketNoPerso}</td>
+ <td>{$nbInsMarketOkPerso+$nbInsMarketNoPerso}</td>
+ </tr>
+ <tr>
+ <td>Par Polytechnique.org</td>
+ <td>{$nbInsMarketOkXorg}</td>
+ <td>{$nbInsMarketNoXorg}</td>
+ <td>{$nbInsMarketOkXorg+$nbInsMarketNoXorg}</td>
+ </tr>
+ <tr>
+ <td>Cette semaine</td>
+ <td>{$nbInsMarketOkWeek}</td>
+ <td>{$nbInsMarketNoWeek}</td>
+ <td>{$nbInsMarketOkWeek+$nbInsMarketNoWeek}</td>
+ </tr>
+ <tr>
+ <td class="titre">Total</td>
+ <td>{$nbInsMarketOkPerso+$nbInsMarketOkXorg}</td>
+ <td>{$nbInsMarketNoPerso+$nbInsMarketNoXorg}</td>
+ <td>{$nbInsMarketOkPerso+$nbInsMarketOkXorg+$nbInsMarketNoPerso+$nbInsMarketNoXorg}</td>
+ </tr>
+</table>
+
{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
</p>
<p>
{if $relance eq '0000-00-00'}
-il n'a jamais été relancé.
+Il n'a jamais été relancé.
{else}
-sa dernière relance date du {$relance|date_format}
+Sa dernière relance date du {$relance|date_format}.
{/if}
</p>
-<p>[<a href='{$path}/insrel?token={xsrf_token}'>le relancer</a>]</p>
+<p>[<a href='{$path}/insrel?token={xsrf_token}'>Le relancer</a>]</p>
{/if}
+{**************************************************************************}
+{* *}
+{* Copyright (C) 2003-2009 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 *}
+{* *}
+{**************************************************************************}
+
<?xml version="1.0" encoding="UTF-8"?>
<xrds:XRDS
xmlns:xrds="xri://$xrds"
</Service>
</XRD>
</xrds:XRDS>
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
<h1>Page d'identité OpenId de {$user->fullName()}</h1>
-<p>OpenID est un système d'authentification décentralisé. Cette page permet
-à des sites web tiers d'identifier {$user->displayName()}, grâce à son compte
+<p>OpenID est un système d'authentification décentralisé. Cette page permet
+à des sites web tiers d'identifier {$user->displayName()}, grâce à son compte
Polytechnique.org.<p>
-<p><a href="Xorg/OpenId">En savoir plus sur OpenId</a></p>
\ No newline at end of file
+<p><a href="Xorg/OpenId">En savoir plus sur OpenId</a></p>
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
<h1>Demande d'identification OpenId</h1>
-<p>Le site <strong>{$relying_party}</strong> demande à confirmer votre identité.</p>
+<p>Un site tiers demande à confirmer ton identité OpenId.
+ {if $sreg_data}
+ De plus, il a demandé à recevoir un certain nombre d'informations
+ te concernant.
+ {/if}
+ Merci de nous indiquer ton choix.
+</p><br />
-{if $sreg_data neq null}
-<p>Les informations suivantes lui seront transmises :</p>
-<ul>
-{foreach from=$sreg_data key=field item=value}
-<li><i>{$field}</i> : {$value}</li>
-{/foreach}
-</ul>
-{/if}
+<form method="POST" action="openid/trust?{$openid_query}">
+ {xsrf_token_field}
+ <table class="bicol">
+ <tr><th colspan="2">Souhaitez-vous confirmer votre identité ?</th></tr>
+ <tr class="impair">
+ <td>Adresse du site :</td>
+ <td><strong>{$relying_party}</strong></td>
+ </tr>
+ {if $sreg_data}
+ <tr class="impair">
+ <td>Informations demandées :</td>
+ <td><ul style="margin-top: 0">
+ {foreach from=$sreg_data key=field item=value}
+ <li><strong>{$field}</strong> ({$value})</li>
+ {/foreach}
+ </ul></td>
+ </tr>
+ {/if}
-<p><strong>Souhaitez-vous confirmer votre identité ?</strong></p>
+ <tr class="pair">
+ <td></td>
+ <td>
+ <label><input type="checkbox" name="trust_always" />
+ Toujours faire confiance à ce site.</label><br />
+ {if $sreg_data}
+ <label><input type="checkbox" checked="checked" name="trust_sreg" />
+ Envoyer les données ci-dessus au site.</label><br />
+ {/if}
+ </td>
+ </tr>
+ <tr class="impair center"><td colspan="2">
+ <input type="submit" name="trust_accept" value="Confirmer" />
+ <input type="submit" name="trust_cancel" value="Annuler" />
+ </td></tr>
+ </table>
+</form>
-<div class="form">
- <form method="post" action="openid/trust?{$query}">
- <input type="checkbox" name="openid_always" /> Toujours faire confiance à ce site<br />
- <input type="submit" name="openid_trust" value="Confirmer" />
- <input type="submit" name="openid_cancel" value="Annuler" />
- </form>
-</div>
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
+{**************************************************************************}
+{* *}
+{* Copyright (C) 2003-2009 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 *}
+{* *}
+{**************************************************************************}
+
<?xml version="1.0" encoding="UTF-8"?>
<xrds:XRDS
xmlns:xrds="xri://$xrds"
</Service>
</XRD>
</xrds:XRDS>
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
<p>{$texte|nl2br}</p>
{/if}
-<p>[<a href='payment'>retour aux Télépaiements</a>]</p>
+<p>[<a href="https://www.polytechnique.org/payment">retour aux Télépaiements</a>]</p>
{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
Tu es inscrit à cet événements.
{if $ev.topay > $ev.paid}
<a href="{$platal->ns}payment/{$p.id}?montant={math equation="a-b" a=$ev.topay b=$ev.paid}">
- Tu dois encore payer {math equation="a-b" a=$ev.topay b=$ev.paid}€
+ Tu dois encore payer {math equation="a-b" a=$ev.topay b=$ev.paid}€.
</a>
{elseif $ev.topay eq $ev.paid}
Tu as déjà réglé l'intégralité de ton inscription ({$ev.topay}€).
{if $sn.error} class="error"{/if} size="25" onkeyup="updateNameDisplay();"/>
</td>
<td>
- {if $sn.has_particle}<input name="search_names[{$i}][particle]" type="checkbox"
- title="Coche cette case si ton nom commence par une particle."
- {if $sn.particle neq ''} checked="checked"{/if} onchange="updateNameDisplay();"/>
- {else}
- <input type="hidden" name="search_names[{$i}][particle]" value=""/>{/if}
+ {if $sn.has_particle}<input type="checkbox"{if $sn.particle neq ''} checked="checked"{/if}
+ title="Coche cette case si ton nom commence par une particle." onchange="toggleParticle({$i});"/>
+ {/if}
+ <input type="hidden" name="search_names[{$i}][particle]" value="{$sn.particle}"/>
{if !$sn.always_displayed}<a href="javascript:removeSearchName({$i})">
{icon name=cross title="Supprimer ce nom"}
</a>{/if}
<td colspan="2" class="smaller">
<div class="titre">Signification des symboles :</div>
{if $grp_public}{icon name=error} L'annuaire du groupe est à visibilité restreinte et ce groupe n'apparaîtra pas sur ta
- fiche{/if}
+ fiche.{/if}
{if $grp_public && $grp_admin}<br />{/if}
- {if $grp_admin}{icon name=wrench} Tu es administrateur du groupe{/if}
+ {if $grp_admin}{icon name=wrench} Tu es administrateur du groupe.{/if}
</td>
</tr>
{/if}
<div id="{$jobid}">
<input type="hidden" name="{$jobpref}[removed]" value="0" />
<input type="hidden" name="{$jobpref}[new]" value="{if $new}1{else}0{/if}" />
+ <input type="hidden" name="{$jobpref}[id]" value="{$i}" />
+ <input type="hidden" name="{$jobpref}[jobid]" value="{$job.jobid}" />
<table id="{$jobid}_grayed" class="bicol" style="display: none; margin-bottom: 1em">
<tr>
<th class="grayed">
</th>
</tr>
</table>
+
<table id="{$jobid}_cont" class="bicol" summary="Entreprise n°{$i+1}" style="margin-bottom: 1em">
<tr>
<th colspan="2" style="text-align: right">
</a>
</th>
</tr>
- {if !$job.tmp_name}
+ {if !$job.tmp_name && !$job.name}
<tr class="{$entreprise}">
<td class="center" colspan="2">
<small>Si ton entreprise ne figure pas dans la liste,
<td class="titre" rowspan="4">Secteur d'activité</td>
<td>
<select name="{$jobpref}[sector]" onchange="updateJobSector({$i}, '')">
- <option value=""> </option>
+ <option value="0"> </option>
{foreach from=$sectors item=item}
<option value="{$item.id}" {if $item.id eq $job.sector}selected="selected"{/if}>
{$item.label}
</tr>
<tr class="pair {$sector}" style="display: none">
<td id="{$jobid}_subSector">
- <input type="hidden" name="{$jobpref}[subSector]" value="{$job.subSector|default:'-1'}" />
+ <input type="hidden" name="{$jobpref}[subSector]" value="{$job.subSector|default:0}" />
</td>
</tr>
<tr class="pair {$sector}" style="display: none">
<td id="{$jobid}_subSubSector">
- <input type="hidden" name="{$jobpref}[subSubSector]" value="{$job.subSubSector|default:'-1'}" />
+ <input type="hidden" name="{$jobpref}[subSubSector]" value="{$job.subSubSector|default:0}" />
</td>
</tr>
<tr class="pair {$sector}" style="display: none">
<?xml version="1.0" encoding="utf-8"?>
<select name="jobs[{$id}][subSector]" {if ($change)}onchange="updateJobSubSector({$id}, '')"{/if}>
- <option value=""></option>
+ <option value="0"></option>
{iterate from=$subSectors item=subSector}
{if $subSector.optgroup}
{if $gp}
<?xml version="1.0" encoding="utf-8"?>
<select name="jobs[{$id}][subSubSector]" onchange="updateJobAlternates({$id})">
- <option value=""></option>
+ <option value="0"></option>
{iterate from=$subSubSectors item=subSubSector}
<option value="{$subSubSector.id}" {if $subSubSector.id eq $sel}selected="selected"{/if}>{$subSubSector.name}</option>
{/iterate}
</div>
{/if}
{if $x.tels}
- {display_phones tels=$x.tels}
+ {display_phones tels=$x.tels dcd=$x.dcd}
{/if}
<div class='spacer'></div>
</div>
{if $x.adr}
<div class="part">
<h2>Contact : </h2>
+ {if $x.dcd}
+ {assign var=address_name value="Dernière adresse"}
+ {else}
+ {assign var=address_name value="Adresse"}
+ {/if}
{foreach from=$x.adr item="address" name=adresses}
{if $smarty.foreach.adresses.iteration is even}
{assign var=pos value="right"}
{assign var=pos value="left"}
{/if}
{if $address.active}
- {include file="geoloc/address.tpl" address=$address titre_div=true titre="Mon adresse actuelle :"
+ {include file="geoloc/address.tpl" address=$address titre_div=true titre=$address_name|@cat:" actuelle :"
for="`$x.prenom` `$x.nom`" pos=$pos}
{elseif $address.secondaire}
- {include file="geoloc/address.tpl" address=$address titre_div=true titre="Adresse secondaire :"
+ {include file="geoloc/address.tpl" address=$address titre_div=true titre=$address_name|@cat:" secondaire :"
for="`$x.prenom` `$x.nom`" pos=$pos}
{else}
- {include file="geoloc/address.tpl" address=$address titre_div=true titre="Adresse principale :"
+ {include file="geoloc/address.tpl" address=$address titre_div=true titre=$address_name|@cat:" principale :"
for="`$x.prenom` `$x.nom`" pos=$pos}
{/if}
{if $smarty.foreach.adresses.iteration is even}<div class="spacer"></div>{/if}
{include file="register/breadcrumb.tpl"}
-<h1>:'(</h1>
+<h1>Confirmation de ton inscription</h1>
-<p class="erreur">
-Une erreur est survenue lors de ton inscription...
-</p>
-<p>
-Contacte nous au plus vite, en nous indiquant ce nombre : {$uid} à l'adresse
-<a href="mailto:support@{#globals.mail.domain#}">support@{#globals.mail.domain#}</a>
-</p>
+<p>Merci {$prenom} d'avoir choisi de t'inscrire. Pour finaliser ton inscription,
+il te suffit de taper ton mot de passe ci-dessous. Tu pourras ensuite librement
+accéder au site, et à notre annuaire en ligne !</p>
+
+<form action="{$smarty.server.REQUEST_URI}" method="post" id="login" onsubmit='doChallengeResponse(); return false;'>
+ <table class="bicol">
+ <tr>
+ <td class="titre">Nom d'utilisateur :</td>
+ <td>{$forlife}</td>
+ </tr>
+ <tr>
+ <td class="titre">Mot de passe :</td>
+ <td><input type="password" name="password" size="10" maxlength="256" /></td>
+ </tr>
+ <tr>
+ <td {popup caption='Connexion permanente' width='300' text='Décoche cette case pour que le site oublie ce navigateur.<br />
+ Il est conseillé de décocher la case si cette machine n\'est pas <b>strictement</b> personnelle'} colspan="2">
+ <label><input type="checkbox" name="remember" checked="checked" />
+ Garder l'accès aux services après déconnexion.
+ </label>
+ </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td><input type="submit" name="submitbtn" value="Envoyer" /></td>
+ </tr>
+ </table>
+</form>
+
+<form action="{$smarty.server.REQUEST_URI}" method="post" id="loginsub">
+ <div>
+ <input type="hidden" name="challenge" value="{$smarty.session.challenge}" />
+ <input type="hidden" name="username" value="{$forlife}" />
+ <input type="hidden" name="remember" value="" />
+ <input type="hidden" name="response" value="" />
+ </div>
+</form>
{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
{$prenom}, félicitations pour ton inscription !
-N'oublie pas de changer ton mot de passe sur le site. C'est très important
-si tu veux garder accès au site et ton email en fonction.
-
Tu as maintenant accès à l'annuaire en ligne, aux services de listes de
diffusion, aux infos promo, etc. N'oublie pas de mettre ta fiche-annuaire
à jour.
Après activation, tes paramètres de connexion seront :
identifiant : {$mailorg}
-mot de passe : {$pass}
-
-Nous te proposerons de remplacer ce mot de passe temporaire par un mot de passe de ton choix.
+mot de passe : celui que tu as choisi
Rends-toi maintenant sur la page web suivante afin d'activer ta pré-inscription :
Nous espérons que tu profiteras pleinement des services en ligne de Polytechnique.org ; s'ils te convainquent, n'oublie pas d'en parler aux camarades autour de toi !
Bien cordialement,
+--
L'équipe de Polytechnique.org,
Le portail des élèves et anciens élèves de l'École polytechnique
{/if}
{math equation="(promo % 100) + 100" promo=$promo}532)<br />
{/if}
Voir sur le GU ou un bulletin de solde pour trouver cette information<br /><br />
- Pour les élèves étrangers voie 2, il est du type :
+ Pour les élèves étrangers voie 2, il peut être aussi du type :
{if $promo < 1999}
{math equation="(promo + 1) % 100" promo=$promo}0XXX
{else}
<h1>Formulaire de pré-inscription</h1>
-<form action="register" method="post">
+<form action="register" method="post" id="changepass2">
{if $smarty.session.sub_state.mailorg2}
<p>
Tu n'as pour le moment aucun homonyme dans notre base de données. Nous allons
donc te donner l'adresse <strong>{$smarty.session.sub_state.bestalias}@{#globals.mail.domain#}</strong>,
en plus de ton adresse à vie <strong>{$smarty.session.sub_state.forlife}@{#globals.mail.domain#}</strong>.
Note que tu pourrais perdre l'adresse <strong>{$smarty.session.sub_state.bestalias}@{#globals.mail.domain#}</strong>
- si un homonyme s'inscrivait — cela reste assez rare.
+ si un homonyme s'inscrivait, même si cela reste assez rare.
</p>
{else}
<p>
t'envoyer tes informations de connexion.
</p>
+ <p>Nous te demandons également un <strong>mot de passe</strong>, qui te permettra de te reconnecter au site ultérieurement.
+ Pour une sécurité optimale, ton mot de passe ne circulera jamais en clair, et sera stocké sous une forme chiffrée
+ irréversiblement sur nos serveurs.
+ </p>
+
+
<table class="bicol">
<tr>
<th colspan="2">
<input type="text" size="35" maxlength="50" name="email" value="{$smarty.post.email}" />
</td>
</tr>
- <tr>
+ <tr class="pair">
<td class="titre">
Date de naissance<br />
<span class="smaller">jour/mois/année</span>
(demandée si tu perds ton mot de passe)
</td>
</tr>
+ <tr class="impair">
+ <td class="titre">
+ Mot de passe<br />
+ <span class="smaller">au moins 6 caractères</span>
+ </td>
+ <td>
+ <input type="hidden" name="response2" />
+ <input type="password" size="10" maxlength="256" name="password" /><br/>
+ <input type="password" size="10" maxlength="256" name="password2" /> (retape ton mot de passe)<br />
+ {checkpasswd prompt="password" text="Terminer la pré-inscription"}
+ </td>
+ </tr>
<tr>
<td colspan="2" class="center">
- <input type="submit" value="Terminer la pré-inscription" />
+ <input type="submit" name="submitn" value="Continuer" onclick="EncryptedResponseInNestedForm(); return false;" />
</td>
</tr>
</table>
</form>
-
+<form action="register" id="changepass">
+ <div>
+ <input type="hidden" name="nouveau" />
+ <input type="hidden" name="nouveau2" />
+ </div>
+</form>
{/if}
{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
La pré-inscription que tu viens de soumettre a été enregistrée.
</p>
<p>
-Les instructions te permettant de valider ton inscription et ton mot de passe pour
-accéder au site viennent de t'être envoyés à l'adresse <strong>{$smarty.session.sub_state.email}</strong>.
+Les instructions te permettant de valider ton inscription viennent de t'être envoyés
+à l'adresse <strong>{$smarty.session.sub_state.email}</strong>.
</p>
<p>
Tu n'as que quelques jours pour suivre ces instructions. Ensuite, la pré-inscription
+++ /dev/null
-{**************************************************************************}
-{* *}
-{* Copyright (C) 2003-2009 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 *}
-{* *}
-{**************************************************************************}
-
-{include file="register/breadcrumb.tpl"}
-
-<h1>Bravo !!!</h1>
-
-<p>
-Tu as maintenant accès au site !<br />
-Ton adresse électronique à vie <strong>{$user->forlifeEmail()}</strong> est déjà ouverte, essaie-la !
-</p>
-<p class="smaller">
- <strong>Remarque :</strong> m4x.org est un domaine "discret" qui veut dire "mail for X" et
- qui comporte exactement les mêmes adresses que le domaine polytechnique.org.
-</p>
-
-
-<h2>Mot de passe</h2>
-
-{if $mdpok}
-
-<p class="erreur">
-Ton mot de passe a bien été mis à jour !
-</p>
-
-{else}
-
-<p>
- Tu as reçu un mot de passe par défaut, si tu souhaites en changer, tu peux le faire ici :<br />
- <strong>Remarque :</strong> il doit faire au moins <strong>6 caractères</strong> et comporter deux types de
- caractères parmi les suivants : lettres minuscules, lettres majuscules, chiffres, caractères spéciaux.
-</p>
-
-<form action="register/success" method="post" id="changepass">
- <table class="tinybicol" cellpadding="3" cellspacing="0">
- <tr>
- <th colspan="2">
- Saisie du nouveau mot de passe
- </th>
- </tr>
- <tr>
- <td class="titre">
- Nouveau mot de passe :
- </td>
- <td>
- <input type="password" size="10" maxlength="10" name="nouveau" />
- </td>
- </tr>
- <tr>
- <td class="titre">
- Retape-le une fois :
- </td>
- <td>
- <input type="password" size="10" maxlength="10" name="nouveau2" />
- </td>
- </tr>
- <tr>
- <td class="titre">Sécurité</td>
- <td>{checkpasswd prompt="nouveau" submit="submitn"}</td>
- </tr>
- <tr>
- <td colspan="2" class="center">
- <input type="submit" value="Changer" name="submitn" onclick="EnCryptedResponse(); return false;" />
- </td>
- </tr>
- </table>
-</form>
-
-<form action="register/success" method="post" id="changepass2">
-<div><input type="hidden" name="response2" value="" /></div>
-</form>
-
-<p class="smaller">
-<strong>N'oublie pas :</strong> en cas de perte de ton mot de passe,
-il existe une procédure de récupération automatique ; mais elle nécessite
-que ton adresse email sur le site soit toujours valable. Dans le cas contraire,
-il te faudra contacter l'équipe support.
-</p>
-
-{/if}
-
-<h2>Rejoindre la communauté</h2>
-
-<form action='register/save' method='post'>
- <p>
- Pour rejoindre la communauté des X sur le web, nous t'invitons vivement à remplir ton profil !
- </p>
-
- <p>
- Cet annuaire n'est pas redondant avec l'annuaire de l'AX ; il est synchronisé automatiquement,
- d'une manière que tu choisis :
- </p>
-
- <dl>
- <dt><input type="checkbox" value="1" checked="checked" name="send_to_ax" disabled="disabled" /> vers l'AX</dt>
- <dd>
- tu peux choisir dans ton profil sur Polytechnique.org de transmettre automatiquement à l'AX certains éléments de ta fiche,
- au fur et à mesure que tu les modifies.
- (Les données transmises seront <strong>uniquement</strong> celles que tu as décidé de transmettre).
- </dd>
- <dt><label><input type='checkbox' value='1' checked="checked" name='register_from_ax_question' /> depuis l'AX</label></dt>
- <dd>
- nous mettons à jour ta fiche depuis les données de l'annuaire de l'AX si tu le souhaites. <br/>
- (si tu ne le souhaites pas, décoche la case ci-dessus)
- </dd>
- </dl>
-
- <p>
- Pour profiter pleinement de ta nouvelle inscription, nous te proposons
- </p>
-
- <dl>
- <dt><label><input type='checkbox' value='1' checked="checked" name='add_to_nl' /> lettre mensuelle*</label></dt>
- <dd>
- de recevoir chaque mois la lettre mensuelle de Polytechnique.org contenant les activités et nouvelles de la communauté des X.
- </dd>
- <dt><label><input type="checkbox" value="1" checked="checked" name="add_to_ax" /> envois de l'AX*</label></dt>
- <dd>
- de recevoir les informations importantes de l'AX.
- </dd>
- <dt><label><input type='checkbox' value='1' checked="checked" name='add_to_promo' /> ta promo*</label></dt>
- <dd>
- de recevoir les informations plus spécifiques de ta promotion pour pouvoir participer plus facilement aux événements
- qu'elle organise. Nous t'inscrivons donc dans le groupe de la promotion {$smarty.session.promo}.
- </dd>
- <dt><label><input type='checkbox' value='1' checked="checked" name='imap' /> sauvegarde des emails</label></dt>
- <dd>
- d'avoir un accès de secours aux 30 derniers jours d'emails reçus sur ton adresse Polytechnique.org.
- </dd>
- </dl>
-
- {if $lists|@count neq 0}
- <p>
- Des camarades souhaitent que tu t'inscrives aux listes suivantes :
- </p>
-
- <dl>
- {foreach from=$lists key=list item=details}
- <dt><label><input type='checkbox' value='1' checked="checked" name="sub_ml[{$list}]" /> {$list}* : {$details.desc}</label></dt>
- {if $details.info}
- <dd>
- {$details.info|nl2br}
- </dd>
- {/if}
- {/foreach}
- </dl>
- {/if}
-
- <p class="smaller">* décoche les cases si tu ne souhaites pas être inscrit à la liste de diffusion correspondante</p>
-
- <div class="center">
- <input type="submit" value="Rejoindre les X sur le Net !" class="erreur" style="background-color: #fff" />
- </div>
-</form>
-
-{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
--- /dev/null
+{**************************************************************************}
+{* *}
+{* Copyright (C) 2003-2009 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 id="reminder">
+ {if $previous_reminder}
+ {include file="reminder/notification.tpl" previous_reminder=$previous_reminder}
+ {/if}
+
+ <fieldset class="warnings">
+ <legend>
+ {if $reminder->warning()}{icon name=error}{else}{icon name=information}{/if}
+ {$reminder->title()}
+ </legend>
+
+ {if $reminder->template()}
+ {include file=$reminder->template()}
+ {else}
+ <div style="margin-bottom: 0.5em">
+ {$reminder->text()}
+ </div>
+ <div class="center">
+ <a href="" onclick="Ajax.update_html('reminder', '{$reminder->baseurl()}/yes'); return false" style="text-decoration: none">
+ {icon name=add} M'inscrire
+ </a> -
+ <a href="" onclick="Ajax.update_html('reminder', '{$reminder->baseurl()}/no'); return false" style="text-decoration: none">
+ {icon name=delete} Ne pas m'inscrire
+ </a> -
+ <a href="" onclick="Ajax.update_html('reminder', '{$reminder->baseurl()}/dismiss'); return false" style="text-decoration: none">
+ {icon name=cross} Décider plus tard
+ </a>
+ {if $reminder->info()}
+ - <a class="popup2" style="text-decoration: none" href="{$reminder->info()}">{icon name=information} En savoir plus</a>
+ {/if}
+ </div>
+ {/if}
+ </fieldset>
+</div>
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
--- /dev/null
+{**************************************************************************}
+{* *}
+{* Copyright (C) 2003-2009 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 *}
+{* *}
+{**************************************************************************}
+
+Des problèmes sont actuellement recontrés sur tes redirections suivantes :
+<ul>
+ {foreach from=$smarty.session.mx_failures item=mail}
+ <li>
+ <span class="erreur">{$mail.mail}</span> :
+ <span class="explication">{$mail.text}</span>
+ </li>
+ {/foreach}
+</ul>
+<div style="text-align: center"><a href="emails/redirect">Gérer mes adresses de redirection</a></div>
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
--- /dev/null
+{**************************************************************************}
+{* *}
+{* Copyright (C) 2003-2009 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 style="margin-bottom: 0.5em">
+ Polytechnique.org te fournit un compte Google Apps qui te permet
+ de disposer des applications web de Google (GMail, Google Calendar,
+ Google Docs, et bien d'autres) sur ton adresse Polytechnique.org
+ habituelle (en savoir plus).
+</div>
+<div class="center">
+ <a href="{$reminder->baseurl()}/yes" style="text-decoration: none">
+ {icon name=add} M'inscrire
+ </a> -
+ <a href="" onclick="Ajax.update_html('reminder', '{$reminder->baseurl()}/no'); return false" style="text-decoration: none">
+ {icon name=delete} Ne pas m'inscrire
+ </a> -
+ <a href="" onclick="Ajax.update_html('reminder', '{$reminder->baseurl()}/dismiss'); return false" style="text-decoration: none">
+ {icon name=cross} Décider plus tard
+ </a> -
+ <a class="popup2" style="text-decoration: none" href="Xorg/GoogleApps">{icon name=information} En savoir plus</a>
+</div>
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
--- /dev/null
+{**************************************************************************}
+{* *}
+{* Copyright (C) 2003-2009 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 *}
+{* *}
+{**************************************************************************}
+
+<form action="{$reminder->baseurl()}/suscribe" method="post">
+ {xsrf_token_field}
+ Des camarades souhaitent que tu t'inscrives aux listes suivantes :
+ <dl>
+ {foreach from=$lists key=list item=details}
+ <dt>
+ <label>
+ <input type='checkbox' value='1' checked="checked" name="sub_ml[{$list}]" />
+ {$list} : {$details.desc}
+ </label>
+ </dt>
+ {if $details.info}
+ <dd>
+ {$details.info|nl2br}
+ </dd>
+ {/if}
+ {/foreach}
+ </dl>
+
+ <div class="center">
+ <input type="submit" value="M'inscrire aux listes" /> -
+ <a href="" onclick="Ajax.update_html('reminder', '{$reminder->baseurl()}/no'); return false" style="text-decoration: none">
+ {icon name=delete} Ne pas m'inscrire
+ </a> -
+ <a href="" onclick="Ajax.update_html('reminder', '{$reminder->baseurl()}/dismiss'); return false" style="text-decoration: none">
+ {icon name=cross} Décider plus tard
+ </a>
+ </div>
+</form>
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
--- /dev/null
+{**************************************************************************}
+{* *}
+{* Copyright (C) 2003-2009 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 *}
+{* *}
+{**************************************************************************}
+
+Tu n'as plus de redirection valide ce qui rend ton adresse Polytechnique.org
+inutilisable. Rends-toi au plus vite sur <a href="emails/redirect">la page de
+gestion des emails</a> pour corriger ce problème.
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
--- /dev/null
+{**************************************************************************}
+{* *}
+{* Copyright (C) 2003-2009 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 id="reminder">
+ <fieldset class="success">
+ <legend>
+ {icon name=information} {$previous_reminder}
+ </legend>
+ Ta demande a bien été prise en compte.
+ </fieldset>
+</div>
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
--- /dev/null
+{**************************************************************************}
+{* *}
+{* Copyright (C) 2003-2009 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 *}
+{* *}
+{**************************************************************************}
+
+{if $profile_incitation}
+ La dernière mise à jour de ta <a href="profile/{$smarty.session.hruid}" class="popup2">fiche</a>
+ date du {$profile_last_update|date_format}. Il est possible qu'elle ne soit pas à jour.
+ Si tu souhaites la modifier,
+ <a href="{$reminder->baseurl()}/profile" style="text-decoration: none">
+ clique ici !</a>
+{elseif $photo_incitation}
+ Tu n'as pas mis de photo de toi sur ta fiche, c'est dommage.
+ <a href="{$reminder->baseurl()}/photo" style="text-decoration: none">
+ Clique ici</a> si tu souhaites en ajouter une.
+{elseif $geocoding_incitation > 0}
+ Parmi tes adresses, il y en a {$geocoding_incitation} que nous n'avons pas pu localiser.
+ <a href="{$reminder->baseurl()}/geoloc" style="text-decoration: none">
+ Clique ici</a> pour rectifier.
+{/if}
+
+<div class="right">
+ <a href="" onclick="Ajax.update_html('reminder', '{$reminder->baseurl()}/dismiss'); return false" style="text-decoration: none">
+ {icon name=cross} Mettre à jour plus tard
+ </a>
+</div>
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
});
-->
{/literal}</script>
+<p class="center">[<a href="search">Revenir à la recherche simple</a>]</p>
<form id="recherche" action="search/adv" method="get">
<table class="bicol" cellpadding="3" summary="Recherche">
<tr>
<th colspan="2">
- Recherche avancée [<a href="search">Revenir à la Recherche simple</a>]
+ Recherche avancée
</th>
</tr>
<tr>
</td>
</tr>
<tr class="noprint">
- <td style="width: 60%">
+ <td style="width: 70%">
<input type="checkbox" name="with_soundex" id="with_soundex" value="1" {if $smarty.request.with_soundex}checked="checked"{/if} /> <label for="with_soundex">Activer la recherche par proximité sonore.</label>
<br /><input type='checkbox' name='order' id="order" value='date_mod' {if $smarty.request.order eq "date_mod"}checked='checked'{/if} /> <label for="order">Mettre les fiches modifiées récemment en premier.</label>
<br /><input type='checkbox' name='nonins' id="nonins" {if $smarty.request.nonins}checked='checked'{/if} value='1' /> <label for="nonins">Chercher uniquement des non inscrits.</label>
</td>
+ <td class="right">
+ <br /><input type="submit" value="Chercher" />
+ </td>
{else}
<tr class="noprint">
<td style="width: 60%">
<input type='text' name="quick" value="{$smarty.request.quick}" style="width: 98%" /><br />
</td>
- {/if}
<td class="right">
- [<a href="search/adv">Recherche avancée</a>]
- <br /><br /><input type="submit" value="Chercher" />
+ <input type="submit" value="Chercher" />
</td>
+ {/if}
</tr>
</table>
</form>
-
-<br />
+{if $smarty.session.auth ge AUTH_COOKIE}
+<p class="center">[<a href="search/adv">Effectuer une recherche avancée</a>]</p>
+{/if}
{if $show_js}
{literal}
<div>
<input type="text" size="20" name="quick" id="quick" class="quick_search"
value="{$smarty.request.quick|default:"Recherche dans l'annuaire"}"
- onfocus="if (this.value === 'Recherche dans l\'annuaire') this.value=''"
- onblur="if (this.value === '') this.value='{$smarty.request.quick|default:"Recherche dans l'annuaire"|escape:javascript}'"/>
- <button type="submit" onclick="if ($('#quick').val() === 'Recherche dans l\'annuaire') $('#quick').val('')">OK</button>
+ onfocus="if (this.value === 'Recherche dans l\'annuaire') this.value='';
+ $('#quick_button').show()"
+ onblur="if (this.value === '') this.value='{$smarty.request.quick|default:"Recherche dans l'annuaire"|escape:javascript}'"
+ />
+ <button id="quick_button" type="submit" style="display: none"
+ onclick="if ($('#quick').val() === 'Recherche dans l\'annuaire') $('#quick').val('')">
+ OK
+ </button>
</div>
</form>
{if $smarty.session.auth gt AUTH_PUBLIC && $smarty.session.notifs}
<td class="titre">Commentaire</td>
<td><textarea name="survey_question[comment]" rows="5" cols="60">{$survey_current.comment}</textarea></td>
</tr>
+ <tr>
+ <td></td>
+ <td class="smaller">
+ <a href="wiki_help/notitle" class="popup3">
+ {icon name=information title="Syntaxe wiki"} Voir la syntaxe wiki autorisée pour le commentaire d'une question
+ </a>
+ </td>
+ </tr>
<script type="text/javascript">//<![CDATA[
var id = new Array();
id['choices'] = {$survey_current.choices|@count};
<td><textarea name="survey_question[description]" rows="5" cols="60">{$survey_current.description}</textarea></td>
</tr>
<tr>
+ <td></td>
+ <td class="smaller">
+ <a href="wiki_help/notitle" class="popup3">
+ {icon name=information title="Syntaxe wiki"} Voir la syntaxe wiki autorisée pour le commentaire du sondage
+ </a>
+ </td>
+ </tr>
+ <tr>
<td class="titre">Date de fin</td>
<td>
{valid_date name="survey_question[end]" value=$survey_current.end to=90}
{/foreach}
</select>
</td>
+ </tr>
<tr id="ln_promo">
<td class="titre">Promotions</td>
<td><input type="text" name="survey_question[promos]" size="50" maxlength="200" value="{$survey_current.promos}"/></td>
{* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *}
{* *}
{**************************************************************************}
-<h1>Sondage : {if $survey_type == 'root'}nouveau sondage{else}nouvelle question{/if}</h1>
+<h1>Sondage :
+ {if $survey_type == 'newsurvey'} créer un nouveau sondage
+ {elseif $survey_type == 'new'} ajouter une question
+ {elseif $survey_type == 'root'} modifier la description
+ {else} modifier une question
+ {/if}
+</h1>
<form action="{$survey_formaction}" method="post">
<input type="hidden" name="survey_action" value="{$survey_action}"/>
<h2>{$squestion.question}</h2>
{if $squestion.comment != ''}
- {$squestion.comment}<br/>
+ {$squestion.comment|miniwiki|smarty:nodefaults}<br/>
{/if}
{assign var='squestion_type' value=$squestion.type}
{include file="survey/show_$squestion_type.tpl"}
<td>
<table class="bicol">
<tr class="pair">
- <td colspan="2">{$survey.description}</td>
+ <td colspan="2">{$survey.description|miniwiki|smarty:nodefaults}</td>
</tr>
<tr>
<td class="titre">Fin du sondage :</td>
<td colspan="2">
Il faut que tu définisses le texte de l'email de confirmation de paiement. Pour ceci, tu peux adapter le modèle qui suit :
<ul>
- <li><strong>Remplace les crochets</strong> ([...]) par le texte que tu désires y voir apparaître</li>
- <li><salutation>, <prenom>, <nom> et <montant> seront <strong>automatiquement</strong> remplacés par les informations adaptées</li>
- <li><a href="wiki_help" class="popup3">{icon name=information} tu peux utiliser une syntaxe wiki pour formatter ton texte</a></li>
+ <li><strong>Remplace les crochets</strong> ([...]) par le texte que tu désires y voir apparaître.</li>
+ <li><salutation>, <prenom>, <nom>, <montant> et <comment> seront <strong>automatiquement</strong> remplacés par les informations adaptées.</li>
+ <li><a href="wiki_help" class="popup3">{icon name=information} Tu peux utiliser une syntaxe wiki pour formatter ton texte.</a></li>
</ul>
{javascript name=ajax}
<div id="pay_preview" style="display: none">
</div>
<textarea name="confirmation" id="payment_text" rows="12" cols="65">{if $paiement_message}{$paiement_message}{else}<salutation> <prenom> <nom>,
-Ton inscription à [METS LE NOM DE L'EVENEMENT ICI] a bien été enregistrée et ton paiement de <montant> a bien été reçu.
+Ton inscription à [METS LE NOM DE L'EVENEMENT ICI] a bien été enregistrée et ton paiement de <montant> a bien
+été reçu avec le commentaire suivant :
+<comment>
[COMPLETE EN PRECISANT LA DATE ET LA PERSONNE A CONTACTER]
--
{$smarty.session.prenom} {$smarty.session.nom}{/if}</textarea><br />
- Page internet de l'événement : <input size="40" name="site" value="{$paiement_site|default:$asso->site|default:$globals->baseurl|cat:'/'|cat:$platal->ns}" /><br />
+ {assign var='asso_url' value=$globals->baseurl|cat:'/'|cat:$platal->ns}
+ Page internet de l'événement : <input size="40" name="site" value="{$paiement_site|default:$asso.site|default:$asso_url}" /><br />
Le nouveau paiement sera activé automatiquement après validation par le trésorier de Polytechnique.org,
ce qui sera fait sous peu.
<script type="text/javascript">//<![CDATA[
Ajouter un membre
</a>
</li>
+ {if $asso.has_ml}
<li>
<a href="{$platal->ns}admin/annuaire">
{icon name=wand title="Synchroniser"}
</a>
</li>
{/if}
+ {/if}
<li>
<a href="{$platal->ns}annuaire/csv/{$asso->diminutif}.csv">
{icon name=page_excel title="Fichier Excel"}
</select>
</td>
</tr>
+ <tr>
+ <td class="titre center" colspan="2">
+ <label><input type="checkbox" value="1" name="ax" {if $asso.ax}checked="checked"{/if} />
+ groupe agréé par l'AX</label>
+ </td>
+ </tr>
</table>
<p></p>
{/if}
+
<table cellpadding="0" cellspacing="0" class='tiny'>
<tr>
<td class="titre">
<tr>
<td class="titre center" colspan="2">
- <label><input type="checkbox" value="1" name="ax" {if $asso->ax}checked="checked"{/if} />
- groupe agréé par l'AX</label>
- </td>
- </tr>
-
- <tr>
- <td class="titre center" colspan="2">
Diffusion de la liste des membres :
<select name="pub">
<option value="public" {if $asso->pub eq 'public'}selected="selected"{/if}>Publique</option>
</table>
</form>
+{literal}
+<script type="text/javascript">
+ $("#email").focus();
+</script>
+{/literal}
+
{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
--- /dev/null
+DROP TABLE IF EXISTS reminder_type;
+
+CREATE TABLE IF NOT EXISTS reminder_type (
+ type_id INT NOT NULL AUTO_INCREMENT,
+ name VARCHAR(255) NOT NULL,
+ weight INT NOT NULL,
+ remind_delay_yes INT NOT NULL DEFAULT 0,
+ remind_delay_no INT NOT NULL DEFAULT 0,
+ remind_delay_dismiss INT NOT NULL DEFAULT 0,
+ PRIMARY KEY(type_id),
+ UNIQUE KEY(name)
+) CHARSET=utf8;
+
+INSERT INTO reminder_type (name, weight, remind_delay_yes, remind_delay_no, remind_delay_dismiss)
+ VALUES ('email_warning', 100, 0, 0, 7),
+ ('no_redirection', 100, 0, 0, 1),
+ ('profile_update', 90, 0, 0, 2),
+ ('nl', 80, 0, 365, 7),
+ ('promotion_ml', 70, 0, 365, 7),
+ ('ml', 70, 0, 0, 7),
+ ('email_backup', 60, 0, 365, 7),
+ ('gapps', 50, 0, 365, 7),
+ ('ax_letter', 50, 0, 365, 14);
+
+DROP TABLE IF EXISTS reminder;
+
+CREATE TABLE IF NOT EXISTS reminder (
+ uid INT NOT NULL,
+ type_id INT NOT NULL,
+ status ENUM('yes', 'no', 'dismiss') NOT NULL,
+ remind_last TIMESTAMP NOT NULL,
+ remind_next TIMESTAMP NULL,
+ PRIMARY KEY(uid, type_id)
+) CHARSET=utf8;
+
+-- vim:set syntax=mysql:
--- /dev/null
+ALTER TABLE groupex.asso CHANGE COLUMN flags flags SET('wiki_desc', 'notif_unsub', 'has_ml') NOT NULL;
+
+-- vim:set syntax=mysql:
--- /dev/null
+ALTER TABLE axletter ADD subset TEXT NULL DEFAULT NULL AFTER promo_max;
+
+-- vim:set syntax=mysql:
DELETE FROM profile_corps_enum
WHERE name = "Ancien élève étranger";
+
+ALTER TABLE watch_profile MODIFY field enum('nom', 'freetext', 'mobile', 'nationalite', 'nationalite2',
+ 'nationalite3', 'nick', 'web', 'networking', 'edus', 'addresses',
+ 'section', 'binets', 'medals', 'cv', 'jobs', 'photo', 'corps');
+
-- vim:set syntax=mysql:
ALTER TABLE watch_profile MODIFY field enum('search_names', 'nom', 'freetext', 'mobile', 'nationalite',
'nationalite2', 'nationalite3', 'nick', 'web', 'networking',
'edus', 'addresses', 'section', 'binets', 'medals', 'cv',
- 'jobs', 'photo');
+ 'jobs', 'photo', 'corps');
UPDATE watch_profile SET field = 'search_names' WHERE field = 'nom' OR field = 'nick';
ALTER TABLE watch_profile MODIFY field enum('search_names', 'freetext', 'mobile', 'nationalite',
'nationalite2', 'nationalite3', 'web', 'networking','edus',
'addresses', 'section', 'binets', 'medals', 'cv', 'jobs',
- 'photo');
+ 'photo', 'corps');
# vim:set syntax=mysql:
+DROP TABLE IF EXISTS profile_addresses;
+
CREATE TABLE IF NOT EXISTS profile_addresses (
pid INT(11) DEFAULT NULL,
jobid INT(6) UNSIGNED DEFAULT NULL,
south FLOAT(10,7) DEFAULT NULL,
east FLOAT(10,7) DEFAULT NULL,
west FLOAT(10,7) DEFAULT NULL,
- updateTime DATE NOT NULL DEFAULT 0,
+ updateTime DATETIME NOT NULL DEFAULT 0,
pub ENUM('public','ax','private') NOT NULL DEFAULT 'private',
comment VARCHAR(255) DEFAULT NULL,
PRIMARY KEY(pid, jobid, type, id),
INDEX countryId (countryId)
) CHARSET=utf8;
+INSERT INTO profile_addresses (pid, id, postalCode, updateTime, pub, comment, latitude, longitude, countryId,
+ type, flags)
+ SELECT uid, adrid, postcode, datemaj, pub, comment, glat, glng, country,
+ IF(FIND_IN_SET('pro', 'statut'), 'job', 'home'),
+ CONCAT(IF(FIND_IN_SET('res-secondaire', 'statut'), 'secondary,', ''),
+ IF(FIND_IN_SET('courrier', 'statut'), 'mail,', ''),
+ IF(FIND_IN_SET('active', 'statut'), 'current,', ''),
+ IF(FIND_IN_SET('temporaire', 'statut'), 'temporary', ''))
+ FROM adresses;
+
CREATE TABLE IF NOT EXISTS geoloc_countries (
iso_3166_1_a2 CHAR(2) NOT NULL,
iso_3166_1_a3 CHAR(3) NOT NULL,
Le 12_secteurs.sql est à faire avant le alternate_subsubsectors.php et pour que ce dernier fonctionne, il faut que le fichier
arbo-UTF8.xml soit dans le même dossier.
+
+Le script addresses.php *doit* être lancé dans un screen - il prend plusieurs jours à tourner.
--- /dev/null
+#!/usr/bin/php5
+<?php
+require_once 'connect.db.inc.php';
+require_once 'geocoding.inc.php';
+
+$globals->debug = 0; // Do not store backtraces.
+
+$res = XDB::query('SELECT MIN(user_id), MAX(user_id)
+ FROM auth_user_md5');
+
+$pids = $res->fetchOneRow();
+
+$minPid = $pids[0];
+$maxPid = $pids[1];
+
+echo "This will take a few minutes.\n".
+
+// Fills the 'text' field in profile_addresses.
+for ($pid = $minPid; $pid < $maxPid + 1; ++$pid) {
+ $res = XDB::iterator("SELECT a.adrid AS id, a.adr1, a.adr2, a.adr3,
+ UNIX_TIMESTAMP(a.datemaj) AS datemaj,
+ a.postcode, a.city, a.cityid, a.region, a.regiontxt,
+ a.pub, a.country, gp.pays AS countrytxt, gp.display,
+ FIND_IN_SET('coord-checked', a.statut) AS checked,
+ FIND_IN_SET('res-secondaire', a.statut) AS secondaire,
+ FIND_IN_SET('courrier', a.statut) AS mail,
+ FIND_IN_SET('temporaire', a.statut) AS temporary,
+ FIND_IN_SET('active', a.statut) AS current,
+ FIND_IN_SET('pro', a.statut) AS pro,
+ a.glat AS precise_lat, a.glng AS precise_lon
+ FROM adresses AS a
+ INNER JOIN geoloc_pays AS gp ON(gp.a2 = a.country)
+ WHERE uid = {?}
+ ORDER BY adrid",
+ $pid);
+
+ while ($address = $res->next()) {
+ $text = get_address_text($address);
+ XDB::iterator('UPDATE profile_addresses
+ SET text = {?}
+ WHERE pid = {?} AND type = {?} AND id = {?}',
+ $text, $pid, $address['pro'] ? 'job' : 'home', $address['id']);
+ }
+}
+
+echo "Filling the 'text' filles is over. Geocoding will start now and will take a few days\n";
+
+// Tries to geocode all the addresses.
+for ($pid = $minPid; $pid < $maxPid + 1; ++$pid) {
+ $res = XDB::iterator('SELECT *
+ FROM profile_addresses
+ WHERE pid = {?}',
+ $pid);
+
+ while ($address = $res->next()) {
+ $updateTime = $address['updateTime'];
+ $gmapsGeocoder = new GMapsGeocoder();
+ $address = $gmapsGeocoder->getGeocodedAddress($address);
+
+ if (!isset($address['geoloc'])) {
+ // TODO: use address and phone classes to update profile_job_enum and profile_phones once they are done.
+
+ XDB::execute('DELETE FROM profile_addresses
+ WHERE pid = {?} AND id = {?} AND type = {?}',
+ $address['pid'], $address['id'], $address['type']);
+
+ Geocoder::getAreaId($address, 'administrativeArea');
+ Geocoder::getAreaId($address, 'subAdministrativeArea');
+ Geocoder::getAreaId($address, 'locality');
+ XDB::execute('INSERT INTO profile_addresses (pid, type, id, flags, accuracy,
+ text, postalText, postalCode, localityId,
+ subAdministrativeAreaId, administrativeAreaId,
+ countryId, latitude, longitude, updateTime, pub, comment,
+ north, south, east, west)
+ VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?},
+ {?}, {?}, FROM_UNIXTIME({?}), {?}, {?}, {?}, {?}, {?}, {?})',
+ $address['pid'], $address['type'], $address['id'], $flags, $address['accuracy'],
+ $address['text'], $address['postalText'], $address['postalCode'], $address['localityId'],
+ $address['subAdministrativeAreaId'], $address['administrativeAreaId'],
+ $address['countryId'], $address['latitude'], $address['longitude'],
+ $updateTime, $address['pub'], $address['comment'],
+ $address['north'], $address['south'], $address['east'], $address['west']);
+ } else {
+ XDB::execute('UPDATE profile_addresses
+ SET postalText = {?}
+ WHERE pid = {?} AND id = {?} AND type = {?}',
+ $address['postalText'], $address['pid'], $address['id'], $address['type']);
+ }
+
+ sleep(60); // So we don't get blacklisted by Google.
+ }
+}
+
+echo "Geocoding is over.\n";
+
+function get_address_text($adr)
+{
+ $t = "";
+ if (isset($adr['adr1']) && $adr['adr1']) $t.= $adr['adr1'];
+ if (isset($adr['adr2']) && $adr['adr2']) $t.= "\n".$adr['adr2'];
+ if (isset($adr['adr3']) && $adr['adr3']) $t.= "\n".$adr['adr3'];
+ $l = "";
+ if (isset($adr['display']) && $adr['display']) {
+ $keys = explode(' ', $adr['display']);
+ foreach ($keys as $key) {
+ if (isset($adr[$key])) {
+ $l .= " ".$adr[$key];
+ } else {
+ $l .= " ".$key;
+ }
+ }
+ if ($l) substr($l, 1);
+ } elseif ($adr['country'] == 'US' || $adr['country'] == 'CA' || $adr['country'] == 'GB') {
+ if ($adr['city']) $l .= $adr['city'].",\n";
+ if ($adr['region']) $l .= $adr['region']." ";
+ if ($adr['postcode']) $l .= $adr['postcode'];
+ } else {
+ if (isset($adr['postcode']) && $adr['postcode']) $l .= $adr['postcode']." ";
+ if (isset($adr['city']) && $adr['city']) $l .= $adr['city'];
+ }
+ if ($l) $t .= "\n".trim($l);
+ if ($adr['country'] != '00' && (!$adr['countrytxt'] || $adr['countrytxt'] == strtoupper($adr['countrytxt']))) {
+ $res = XDB::query('SELECT pays
+ FROM geoloc_pays
+ WHERE a2 = {?}',
+ $adr['country']);
+ $adr['countrytxt'] = $res->fetchOneCell();
+ }
+ if (isset($adr['countrytxt']) && $adr['countrytxt']) {
+ $t .= "\n".$adr['countrytxt'];
+ }
+ return trim($t);
+}
+
+/* vim:set et sw=4 sts=4 ts=4: */
+?>