From 85ddf64feaef343f5eb818bff53fc3c718428c59 Mon Sep 17 00:00:00 2001 From: =?utf8?q?St=C3=A9phane=20Jacob?= Date: Wed, 23 Feb 2011 16:08:16 +0100 Subject: [PATCH] Adapts Xorg MLs and aliases handling to new mail chain. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Jacob --- configs/platal.ini | 4 ++ include/emails.inc.php | 97 +++++++++++++++++++++++++ include/validations/listes.inc.php | 49 ++++--------- modules/lists.php | 64 ++++++----------- modules/xnetlists.php | 137 +++++++++++------------------------- templates/xnetlists/alias-admin.tpl | 25 ++----- templates/xnetlists/index.tpl | 14 ++-- 7 files changed, 188 insertions(+), 202 deletions(-) diff --git a/configs/platal.ini b/configs/platal.ini index c6ae06f..4764c71 100644 --- a/configs/platal.ini +++ b/configs/platal.ini @@ -256,6 +256,10 @@ vhost_sep = "_" ; Maximum number of mails an instance of the moderation cron accepts to deliver. max_mail_per_min = 400 +; $globals->lists->redirect_domain +; Domain where mailing list emails are redirected. +redirect_domain = "" + ; The mail section contains parameters used to interacts with email routing [Mail] diff --git a/include/emails.inc.php b/include/emails.inc.php index 4561329..3af0096 100644 --- a/include/emails.inc.php +++ b/include/emails.inc.php @@ -24,6 +24,103 @@ define('ERROR_INACTIVE_REDIRECTION', 2); define('ERROR_INVALID_EMAIL', 3); define('ERROR_LOOP_EMAIL', 4); +function add_to_list_alias(User $user, $local_part, $domain) +{ + Platal::assert($user !== null); + + XDB::execute('INSERT IGNORE INTO email_virtual (email, domain, redirect, type) + SELECT {?}, id, {?}, {?} + FROM email_virtual_domains + WHERE name = {?}', + $local_part, $user->forlifeEmail(), $type, $domain); +} + +function delete_from_list_alias(User $user, $local_part, $domain) +{ + Platal::assert($user !== null); + + XDB::execute('DELETE v + FROM email_virtual AS v + INNER JOIN email_virtual_domains AS m ON (v.domain = m.id) + INNER JOIN email_virtual_domains AS d ON (d.aliasing = m.id) + WHERE v.email = {?} AND d.name = {?} AND v.redirect = {?} AND type = {?}', + $local_part, $domain, $user->forlifeEmail(), $type); +} + +function list_alias_members($local_part, $domain) +{ + $emails = XDB::fetchColumn('SELECT DISTINCT(redirect) + FROM email_virtual AS v + INNER JOIN email_virtual_domains AS m ON (v.domain = m.id) + INNER JOIN email_virtual_domains AS d ON (d.aliasing = m.id) + WHERE v.email = {?} AND d.name = {?} AND type = \'user\'', + $local_part, $domain); + + $members = array(); + foreach ($emails as $email) { + $members[] = User::getSilent($email); + } + + return $members; +} + +function delete_list_alias($local_part, $domain) +{ + XDB::execute('DELETE v + FROM email_virtual AS v + INNER JOIN email_virtual_domains AS m ON (v.domain = m.id) + INNER JOIN email_virtual_domains AS d ON (d.aliasing = m.id) + WHERE v.email = {?} AND d.name = {?} AND type = \'user\'', + $local_part, $domain); +} + +function iterate_list_alias($domain) +{ + return XDB::fetchColumn('SELECT CONCAT(v.email, \'@\', m.name) + FROM email_virtual AS v + INNER JOIN email_virtual_domains AS m ON (v.domain = m.id) + WHERE m.name = {?} AND v.type = \'user\' + GROUP BY v.email', + $domain); +} + +function create_list($local_part, $domain) +{ + global $globals; + + $redirect = $domain . '_' . $local_part . '+'; + foreach(array('post', 'owner', 'admin', 'bounces', 'unsubscribe') as $suffix) { + XDB::execute('INSERT IGNORE INTO email_virtual (email, domain, redirect, type) + SELECT {?}, id, {?}, \'list\' + FROM email_virtual_domains + WHERE name = {?}', + ($suffix == 'post') ? $local_part : $local_part . '-' . $suffix, + $redirect . $suffix . '@' . $globals->lists->redirect_domain, $domain); + } +} + +function delete_list($local_part, $domain) +{ + global $globals; + + $redirect = $domain . '_' . $local_part . '+'; + foreach(array('post', 'owner', 'admin', 'bounces', 'unsubscribe') as $suffix) { + XDB::execute('DELETE email_virtual + WHERE redirect = {?} AND type = \'list\'', + $redirect . $suffix . '@' . $globals->lists->redirect_domain); + } +} + +function list_exist($local_part, $domain) +{ + return XDB::fetchOneCell('SELECT COUNT(*) + FROM email_virtual AS v + INNER JOIN email_virtual_domains AS m ON (v.domain = m.id) + INNER JOIN email_virtual_domains AS d ON (m.id = d.aliasing) + WHERE v.email = {?} AND d.name = {?}', + $local_part, $domain); +} + // function mark_broken_email() {{{1 function mark_broken_email($email, $admin = false) { diff --git a/include/validations/listes.inc.php b/include/validations/listes.inc.php index 806ceae..197d187 100644 --- a/include/validations/listes.inc.php +++ b/include/validations/listes.inc.php @@ -43,7 +43,7 @@ class ListeReq extends Validate // {{{ constructor public function __construct(User $_user, $_asso, $_liste, $_domain, $_desc, $_advertise, - $_modlevel, $_inslevel, $_owners, $_members, $_stamp=0) + $_modlevel, $_inslevel, $_owners, $_members, $_stamp = 0) { parent::__construct($_user, false, 'liste', $_stamp); @@ -127,48 +127,23 @@ class ListeReq extends Validate public function commit() { - global $globals; + require_once 'emails.inc.php'; - if ($this->asso == "alias") { - $new = $this->liste . '@' . $this->domain; - XDB::query('INSERT INTO virtual (alias, type) VALUES({?}, "user")', $new); + if ($this->asso == 'alias') { foreach ($this->members as $member) { $user = User::get($member); - if ($user != null) { - XDB::query( - "INSERT INTO virtual_redirect (vid, redirect) - SELECT vid, {?} - FROM virtual - WHERE alias = {?}", $user->forlifeEmail(), $new); - } + add_to_list_alias($user, $this->liste, $this->domain); } - return 1; - } - - $list = new MMList(S::user(), $this->domain); - $ret = $list->create_list($this->liste, utf8_decode($this->desc), $this->advertise, - $this->modlevel, $this->inslevel, - $this->owners, $this->members); - $liste = strtolower($this->liste); - if ($ret && !$this->asso) { - foreach(Array($liste, $liste . "-owner", $liste . "-admin", $liste . "-bounces", $liste . "-unsubscribe") as $l) { - XDB::execute("INSERT INTO aliases (alias, type) VALUES({?}, 'liste')", $l); - } - } elseif ($ret) { - foreach (Array('', 'owner', 'admin', 'bounces', 'unsubscribe') as $app) { - $mdir = $app == '' ? '+post' : '+' . $app; - if (!empty($app)) { - $app = '-' . $app; - } - $red = $this->domain . '_' . $liste; - XDB::execute('INSERT INTO virtual (alias, type) - VALUES({?}, {?})', $liste . $app . '@' . $this->domain, 'list'); - XDB::execute('INSERT INTO virtual_redirect (vid, redirect) - VALUES ({?}, {?})', XDB::insertId(), - $red . $mdir . '@listes.polytechnique.org'); + } else { + $list = new MMList(S::user(), $this->domain); + $success = $list->create_list($this->liste, utf8_decode($this->desc), $this->advertise, + $this->modlevel, $this->inslevel, + $this->owners, $this->members); + if ($success) { + create_list($this->liste, $this->domain); } + return $success; } - return $ret; } // }}} diff --git a/modules/lists.php b/modules/lists.php index 60ca0ee..5c4ec4d 100644 --- a/modules/lists.php +++ b/modules/lists.php @@ -239,17 +239,17 @@ class ListsModule extends PLModule S::assert_xsrf_token(); } - $asso = Post::v('asso'); - $liste = Post::v('liste'); + $asso = Post::t('asso'); + $list = strtolower(Post::t('liste')); - if (empty($liste)) { + if (empty($list)) { $page->trigError('Le champ « adresse souhaitée Â» est vide.'); } - if (!preg_match("/^[a-zA-Z0-9\-]*$/", $liste)) { + if (!preg_match("/^[a-zA-Z0-9\-]*$/", $list)) { $page->trigError('Le nom de la liste ne doit contenir que des lettres non accentuées, chiffres et tirets.'); } - if (($asso == "binet") || ($asso == "alias")) { + if (($asso == 'binet') || ($asso == 'alias')) { $promo = Post::i('promo'); $domain = $promo . '.' . $globals->mail->domain; @@ -257,35 +257,25 @@ class ListsModule extends PLModule $page->trigError('La promotion est mal renseignée, elle doit être du type : 2004.'); } - $new = $liste . '@' . $domain; - $res = XDB::query('SELECT COUNT(*) FROM virtual WHERE alias={?}', $new); - - } else { - if ($asso == "groupex") { - $groupex_name = Post::v('groupex_name'); - - $res_groupe = XDB::query('SELECT mail_domain FROM groups WHERE nom={?}', $groupex_name); - $domain = $res_groupe->fetchOneCell(); + } elseif ($asso == 'groupex') { + $domain = XDB::fetchOneCell('SELECT mail_domain + FROM groups + WHERE nom = {?}', + Post::t('groupex_name')); if (!$domain) { $page->trigError('Il n\'y a aucun groupe de ce nom sur Polytechnique.net.'); } - - $new = $liste . '@' . $domain; - $res = XDB::query('SELECT COUNT(*) FROM virtual WHERE alias={?}', $new); - } else { - $res = XDB::query("SELECT COUNT(*) FROM aliases WHERE alias={?}", $liste); - $domain = $globals->mail->domain; - } + } else { + $domain = $globals->mail->domain; } - $n = $res->fetchOneCell(); - - if ($n) { + require_once 'emails.inc.php'; + if (list_exist($list, $domain)) { $page->trigError("L'« adresse souhaitée Â» est déjà prise."); } - if (!Post::v('desc')) { + if (!Post::t('desc')) { $page->trigError('Le sujet est vide.'); } @@ -293,15 +283,15 @@ class ListsModule extends PLModule $page->trigError('Il n\'y a pas de gestionnaire.'); } - if (count($members)<4) { + if (count($members) < 4) { $page->trigError('Il n\'y a pas assez de membres.'); } if (!$page->nb_errs()) { $page->trigSuccess('Demande de création envoyée !'); $page->assign('created', true); - $req = new ListeReq(S::user(), $asso, $liste, $domain, - Post::v('desc'), Post::i('advertise'), + $req = new ListeReq(S::user(), $asso, $list, $domain, + Post::t('desc'), Post::i('advertise'), Post::i('modlevel'), Post::i('inslevel'), $owners, $members); $req->submit(); @@ -805,26 +795,14 @@ class ListsModule extends PLModule } $domain = $this->prepare_client($page); - if ($domain == $globals->mail->domain || $domain == $globals->mail->domain2) { - $domain = ''; - $table = 'aliases'; - $type = 'liste'; - } else { - $domain = '@' . $domain; - $table = 'virtual'; - $type = 'list'; - } - $page->changeTpl('lists/delete.tpl'); if (Post::v('valid') == 'OUI') { S::assert_xsrf_token(); if ($this->client->delete_list($liste, Post::b('del_archive'))) { - foreach (array('', '-owner', '-admin', '-bounces', '-unsubscribe') as $app) { - XDB::execute("DELETE FROM $table - WHERE type={?} AND alias={?}", - $type, $liste.$app.$domain); - } + require_once 'emails.inc.php'; + + delete_list($liste, $domain); $page->assign('deleted', true); $page->trigSuccess('La liste a été détruite !'); } else { diff --git a/modules/xnetlists.php b/modules/xnetlists.php index a7a2ff0..3f0e792 100644 --- a/modules/xnetlists.php +++ b/modules/xnetlists.php @@ -73,6 +73,7 @@ class XnetListsModule extends ListsModule function handler_lists($page) { global $globals; + require_once 'emails.inc.php'; if (!$globals->asso('mail_domain')) { return PL_NOT_FOUND; @@ -94,28 +95,15 @@ class XnetListsModule extends ListsModule if (Post::has('del_alias') && may_update()) { S::assert_xsrf_token(); - $alias = Post::v('del_alias'); - // prevent group admin from erasing aliases from other groups - $alias = substr($alias, 0, strpos($alias, '@')).'@'.$globals->asso('mail_domain'); - XDB::query( - 'DELETE FROM r, v - USING virtual AS v - LEFT JOIN virtual_redirect AS r USING(vid) - WHERE v.alias={?}', $alias); - $page->trigSuccess(Post::v('del_alias')." supprimé !"); + $alias = Post::t('del_alias'); + list($local_part, ) = explode('@', $alias); + delete_list_alias($local_part, $globals->asso('mail_domain')); + $page->trigSuccess($alias . ' supprimé !'); } $listes = $this->client->get_lists(); $page->assign('listes', $listes); - - $alias = XDB::iterator( - 'SELECT alias,type - FROM virtual - WHERE alias - LIKE {?} AND type="user" - ORDER BY alias', '%@'.$globals->asso('mail_domain')); - $page->assign('alias', $alias); - + $page->assign('aliases', iterate_list_alias($globals->asso('mail_domain'))); $page->assign('may_update', may_update()); if (count($listes) > 0 && !$globals->asso('has_ml')) { @@ -142,61 +130,44 @@ class XnetListsModule extends ListsModule S::assert_xsrf_token(); } - if (!Post::has('liste') || !Post::v('liste')) { + if (!Post::has('liste') || !Post::t('liste')) { $page->trigError('Le champs « adresse souhaitée Â» est vide.'); return; } - $liste = strtolower(Post::v('liste')); - - if (!preg_match("/^[a-zA-Z0-9\-]*$/", $liste)) { + $list = strtolower(Post::t('liste')); + if (!preg_match("/^[a-zA-Z0-9\-]*$/", $list)) { $page->trigError('le nom de la liste ne doit contenir que des lettres non accentuées, chiffres et tirets'); return; } - $new = $liste.'@'.$globals->asso('mail_domain'); - $res = XDB::query('SELECT alias FROM virtual WHERE alias={?}', $new); - - if ($res->numRows()) { - $page->trigError('cet alias est déjà pris'); + require_once 'emails.inc.php'; + if (list_exist($list, $globals->asso('mail_domain'))) { + $page->trigError('Cet alias est déjà pris.'); return; } - if (!Post::v('desc')) { - $page->trigError('le sujet est vide'); + if (!Post::t('desc')) { + $page->trigError('Le sujet est vide.'); return; } - $ret = $this->client->create_list( - $liste, utf8_decode(Post::v('desc')), Post::v('advertise'), - Post::v('modlevel'), Post::v('inslevel'), - array(S::user()->forlifeEmail()), array(S::user()->forlifeEmail())); - - $dom = strtolower($globals->asso("mail_domain")); - $red = $dom.'_'.$liste; + $success = $this->client->create_list($list, utf8_decode(Post::t('desc')), Post::t('advertise'), + Post::t('modlevel'), Post::t('inslevel'), + array(S::user()->forlifeEmail()), array(S::user()->forlifeEmail())); - if (!$ret) { + if (!$success) { $page->kill("Un problème est survenu, contacter " ."support@m4x.org"); return; } - foreach (array('', 'owner', 'admin', 'bounces', 'unsubscribe') as $app) { - $mdir = $app == '' ? '+post' : '+' . $app; - if (!empty($app)) { - $app = '-' . $app; - } - XDB::execute('INSERT INTO virtual (alias,type) - VALUES({?},{?})', $liste. $app . '@'.$dom, 'list'); - XDB::execute('INSERT INTO virtual_redirect (vid,redirect) - VALUES ({?}, {?})', XDB::insertId(), - $red . $mdir . '@listes.polytechnique.org'); - } + create_list($list, $globals->asso('mail_domain')); XDB::execute("UPDATE groups SET flags = CONCAT_WS(',', IF(flags = '', NULL, flags), 'has_ml') WHERE id = {?}", $globals->asso('id')); - pl_redirect('lists/admin/'.$liste); + pl_redirect('lists/admin/' . $list); } function handler_sync($page, $liste = null) @@ -242,53 +213,30 @@ class XnetListsModule extends ListsModule } $page->changeTpl('xnetlists/alias-admin.tpl'); + require_once 'emails.inc.php'; + list($local_part, $domain) = explode('@', $lfull); if (Env::has('add_member')) { S::assert_xsrf_token(); - $add = Env::t('add_member'); - $user = User::getSilent($add); + $email = Env::t('add_member'); + $user = User::getSilent($email); if ($user) { - $add = $user->forlifeEmail(); - } else if (!User::isForeignEmailAddress($add)) { - $add = null; - } - if (!empty($add)) { - XDB::execute('INSERT INTO virtual_redirect (vid, redirect) - SELECT vid, {?} - FROM virtual - WHERE alias = {?}', strtolower($add), $lfull); - $page->trigSuccess($add . ' ajouté.'); + add_to_list_alias($user, $local_part, $domain); + $page->trigSuccess($email . ' ajouté.'); } else { - $page->trigError($add . " n'existe pas."); + $page->trigError($email . " n'existe pas."); } } if (Env::has('del_member')) { S::assert_xsrf_token(); - XDB::query( - "DELETE FROM virtual_redirect - USING virtual_redirect - INNER JOIN virtual USING(vid) - WHERE redirect={?} AND alias={?}", Env::v('del_member'), $lfull); - pl_redirect('alias/admin/'.$lfull); - } - global $globals; - $emails = XDB::fetchColumn('SELECT redirect - FROM virtual_redirect AS vr - INNER JOIN virtual AS v USING(vid) - WHERE v.alias = {?} - ORDER BY redirect', $lfull); - $mem = array(); - foreach ($emails as $email) { - $user = User::getSilent($email); - if ($user) { - $mem[] = array('user' => $user, 'email' => $email); - } else { - $mem[] = array('email' => $email); - } + $user = User::getSilent(Env::t('del_member')); + delete_from_list_alias($user, $local_part, $domain); + $page->trigSuccess($user->fullName() . ' supprimé.'); } - $page->assign('mem', $mem); + + $page->assign('members', list_alias_members($local_part, $domain)); } function handler_acreate($page) @@ -310,24 +258,21 @@ class XnetListsModule extends ListsModule $page->trigError('Le champs « adresse souhaitée Â» est vide.'); return; } - $liste = Post::v('liste'); - if (!preg_match("/^[a-zA-Z0-9\-\.]*$/", $liste)) { - $page->trigError('le nom de l\'alias ne doit contenir que des lettres,' - .' chiffres, tirets et points'); + $list = Post::v('liste'); + if (!preg_match("/^[a-zA-Z0-9\-\.]*$/", $list)) { + $page->trigError('Le nom de l\'alias ne doit contenir que des lettres,' + .' chiffres, tirets et points.'); return; } - $new = $liste.'@'.$globals->asso('mail_domain'); - $res = XDB::query('SELECT COUNT(*) FROM virtual WHERE alias = {?}', $new); - $n = $res->fetchOneCell(); - if ($n) { - $page->trigError('cet alias est déjà pris'); + require_once 'emails.inc.php'; + if (list_exist($list, $globals->asso('mail_domain'))) { + $page->trigError('Cet alias est déjà pris.'); return; } - XDB::query('INSERT INTO virtual (alias,type) VALUES({?}, "user")', $new); - - pl_redirect("alias/admin/$new"); + add_to_list_alias(S::user(), $list, $globals->asso('mail_domain')); + pl_redirect('alias/admin/' . $list . '@' . $globals->asso('mail_domain')); } function handler_profile($page, $user = null) diff --git a/templates/xnetlists/alias-admin.tpl b/templates/xnetlists/alias-admin.tpl index 654c45f..3a8680a 100644 --- a/templates/xnetlists/alias-admin.tpl +++ b/templates/xnetlists/alias-admin.tpl @@ -23,29 +23,16 @@

[retour à la page des listes]

Membres de {$platal->argv[1]}

- - {if $mem|@count} - {foreach from=$mem item=m} + {if $members|@count} + {foreach from=$members item=member} - + @@ -54,7 +41,7 @@ {else} {/if} diff --git a/templates/xnetlists/index.tpl b/templates/xnetlists/index.tpl index 75dcdbc..3bae8b3 100644 --- a/templates/xnetlists/index.tpl +++ b/templates/xnetlists/index.tpl @@ -112,18 +112,18 @@ t'empêcherait de t'y réabonner par la suite sans l'aide d'un administrateur. Alias - {if $alias->total()} - {iterate from=$alias item=a} + {if $aliases|@count} + {foreach from=$aliases item=alias} {if $may_update} - - - + + + {else} - + {/if} - {/iterate} + {/foreach} {else} Aucun alias pour ce groupe -- 2.1.4
- {if $m.user} - {if $m.admin}{/if} - {$m.user->fullName()} - {if $m.admin}{/if} - {else} - {$m.email} - {/if} - - {if $m.user} - {if $m.admin}{/if} - {$m.user->promo()} - {if $m.admin}{/if} - {/if} + {$member->fullName()} {$member->promo()} - + {icon name=delete title='retirer membre'}
- aucun membre… + aucun membre…
{icon name=email title="email"}{$a.alias}{icon name=delete title='supprimer'}{icon name=email title="email"}{$alias}{icon name=delete title='supprimer'}{icon name=email title="email"} {$a.alias}{icon name=email title="email"} {$alias}