X-Git-Url: http://git.polytechnique.org/?a=blobdiff_plain;f=include%2Femails.inc.php;h=19c172e20159f4ee1ea4fc9db3ddef5da9bfb328;hb=1e7aeba246f8a66530e8d4108c7b14bd68a6dc02;hp=0ff0d3375139b371009d686ec4970aae8625fb62;hpb=9f3f87bc8e2fc21c6b160f0db67bfd1b52d40007;p=platal.git diff --git a/include/emails.inc.php b/include/emails.inc.php index 0ff0d33..19c172e 100644 --- a/include/emails.inc.php +++ b/include/emails.inc.php @@ -24,38 +24,79 @@ 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, $type = 'alias') +// Checks if an email update is required in MLs and aliases. +// This occurs when the user don't have email permissions and her email has changed. +function require_email_update(User $user, $new_email) { - Platal::assert($user !== null); + Platal::assert(!is_null($user), 'User cannot be null.'); + + return !$user->checkPerms(User::PERM_MAIL) && $new_email != $user->forlifeEmail(); +} + +function format_email_alias($email) +{ + if ($user = User::getSilent($email)) { + return $user->forlifeEmail(); + } + if (isvalid_email($email)) { + return $email; + } + return null; +} + +function add_to_list_alias($email, $local_part, $domain, $type = 'alias') +{ + $email = format_email_alias($email); + if (is_null($email)) { + return false; + } 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); + $local_part, $email, $type, $domain); + return true; } -function delete_from_list_alias(User $user, $local_part, $domain, $type = 'alias') +function delete_from_list_alias($email, $local_part, $domain, $type = 'alias') { - Platal::assert($user !== null); + $email = format_email_alias($email); + if (is_null($email)) { + return false; + } 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); + $local_part, $domain, $email, $type); + return true; } -function update_list_alias(User $user, $former_email, $local_part, $domain, $type = 'alias') +function update_list_alias($email, $former_email, $local_part, $domain, $type = 'alias') { - Platal::assert($user !== null); + $email = format_email_alias($email); + if (is_null($email)) { + return false; + } XDB::execute('UPDATE email_virtual AS v INNER JOIN email_virtual_domains AS d ON (v.domain = d.id) SET v.redirect = {?} WHERE v.redirect = {?} AND d.name = {?} AND v.email = {?} AND v.type = {?}', - $user->forlifeEmail(), $former_email, $domain, $local_part, $type); + $email, $former_email, $domain, $local_part, $type); + return true; +} + +// Updates an email in all aliases (groups and events). +function update_alias_user($former_email, $new_email) +{ + XDB::execute('UPDATE email_virtual + SET redirect = {?} + WHERE redirect = {?} AND (type = \'alias\' OR type = \'event\')', + $new_email, $former_email); } function list_alias_members($local_part, $domain) @@ -67,12 +108,20 @@ function list_alias_members($local_part, $domain) WHERE v.email = {?} AND d.name = {?} AND type = \'alias\'', $local_part, $domain); - $members = array(); + $users = array(); + $nonusers = array(); foreach ($emails as $email) { - $members[] = User::getSilent($email); + if ($user = User::getSilent($email)) { + $users[] = $user; + } else { + $nonusers[] = $email; + } } - return $members; + return array( + 'users' => $users, + 'nonusers' => $nonusers + ); } function delete_list_alias($local_part, $domain) @@ -116,8 +165,8 @@ function delete_list($local_part, $domain) $redirect = $domain . '_' . $local_part . '+'; foreach(array('post', 'owner', 'admin', 'bounces', 'unsubscribe') as $suffix) { - XDB::execute('DELETE email_virtual - WHERE redirect = {?} AND type = \'list\'', + XDB::execute('DELETE FROM email_virtual + WHERE redirect = {?} AND type = \'list\'', $redirect . $suffix . '@' . $globals->lists->redirect_domain); } } @@ -140,7 +189,8 @@ function mark_broken_email($email, $admin = false) return; } - $user = XDB::fetchOneAssoc('SELECT r1.uid, r1.broken_level != 0 AS broken, a.hruid, COUNT(r2.uid) AS nb_mails, a.full_name, s.email AS alias + $user = XDB::fetchOneAssoc('SELECT r1.uid, r1.broken_level != 0 AS broken, COUNT(r2.uid) AS nb_mails, + s.email AS alias, DATE_ADD(r1.last, INTERVAL 14 DAY) < CURDATE() as notify FROM email_redirect_account AS r1 INNER JOIN accounts AS a ON (a.uid = r1.uid) INNER JOIN email_source_account AS s ON (a.uid = s.uid AND s.flags = \'bestalias\') @@ -176,30 +226,13 @@ function mark_broken_email($email, $admin = false) // eventually selects a new bestalias when required. function fix_bestalias(User $user) { - // First check if best_domain is properly set. - $count = XDB::fetchOneCell('SELECT COUNT(*) - FROM accounts AS a - INNER JOIN email_virtual_domains AS d ON (d.id = a.best_domain) - INNER JOIN email_virtual_domains AS m ON (d.aliasing = m.id) - WHERE a.uid = {?} AND m.name = {?}', - $user->id(), $user->mainEmailDomain()); - if ($count == 0) { - XDB::execute('UPDATE accounts AS a - INNER JOIN email_virtual_domains AS d ON (d.name = {?}) - SET a.best_domain = d.id - WHERE a.uid = {?}', - $user->mainEmailDomain(), $user->id()); - } + // First check if the bestalias is properly set. + $alias_count = XDB::fetchOneCell('SELECT COUNT(*) + FROM email_source_account + WHERE uid = {?} AND FIND_IN_SET(\'bestalias\', flags) AND expire IS NULL', + $user->id()); - // Then check the alias. - $count = XDB::fetchOneCell('SELECT COUNT(*) - FROM email_source_account - WHERE uid = {?} AND FIND_IN_SET(\'bestalias\', flags) AND expire IS NULL', - $user->id()); - - if ($count == 1) { - return; - } elseif ($count > 1) { + if ($alias_count > 1) { // If too many bestaliases, delete the bestalias flag from all this // user's emails (this should never happen). XDB::execute("UPDATE email_source_account @@ -207,15 +240,37 @@ function fix_bestalias(User $user) WHERE uid = {?}", $user->id()); } + if ($alias_count != 1) { + // If no bestalias is selected, we choose the shortest email which is not + // related to a usage name and contains a '.'. + XDB::execute("UPDATE email_source_account + SET flags = CONCAT_WS(',', IF(flags = '', NULL, flags), 'bestalias') + WHERE uid = {?} AND expire IS NULL + ORDER BY NOT FIND_IN_SET('usage', flags), email LIKE '%.%', LENGTH(email) + LIMIT 1", + $user->id()); + } + + // First check if best_domain is properly set. + $domain_count = XDB::fetchOneCell('SELECT COUNT(*) + FROM accounts AS a + INNER JOIN email_source_account AS s ON (s.uid = a.uid AND FIND_IN_SET(\'bestalias\', s.flags)) + INNER JOIN email_virtual_domains AS d ON (d.id = a.best_domain) + INNER JOIN email_virtual_domains AS m ON (d.aliasing = m.id) + INNER JOIN email_virtual_domains AS v ON (v.aliasing = m.id AND v.id = s.domain) + WHERE a.uid = {?} AND (m.name = {?} OR m.name = {?})', + $user->id(), $user->mainEmailDomain(), Platal::globals()->mail->alias_dom); + + if ($domain_count == 0) { + XDB::execute('UPDATE accounts AS a + INNER JOIN email_source_account AS s ON (s.uid = a.uid AND FIND_IN_SET(\'bestalias\', s.flags)) + INNER JOIN email_virtual_domains AS d ON (d.aliasing = s.domain AND (d.name = {?} OR d.name = {?})) + SET a.best_domain = d.id + WHERE a.uid = {?}', + $user->mainEmailDomain(), Platal::globals()->mail->alias_dom, $user->id()); + } + - // If no bestalias is selected, we choose the shortest email which is not - // related to a usage name and contains a '.'. - XDB::execute("UPDATE email_source_account - SET flags = CONCAT_WS(',', IF(flags = '', NULL, flags), 'bestalias') - WHERE uid = {?} AND expire IS NULL - ORDER BY NOT FIND_IN_SET('usage', flags), email LIKE '%.%', LENGTH(email) - LIMIT 1", - $user->id()); } // function valide_email() {{{1 @@ -342,7 +397,8 @@ class Bogo $this->user = &$user; $res = XDB::fetchOneAssoc('SELECT COUNT(DISTINCT(action)) AS action_count, COUNT(redirect) AS redirect_count, action FROM email_redirect_account - WHERE uid = {?} AND (type = \'smtp\' OR type = \'googleapps\') AND flags = \'active\'', + WHERE uid = {?} AND (type = \'smtp\' OR type = \'googleapps\') AND flags = \'active\' + GROUP BY uid', $user->id()); if ($res['redirect_count'] == 0) { return; @@ -568,7 +624,8 @@ class Email // Google Apps storage is available for users with valid Google Apps account. require_once 'googleapps.inc.php'; - if ($globals->mailstorage->googleapps_domain && + if ($user->checkPerms('gapps') && + $globals->mailstorage->googleapps_domain && GoogleAppsAccount::account_status($user->id()) == 'active') { $storages[] = 'googleapps'; } @@ -584,7 +641,7 @@ class Email static public function activate_storage(User $user, $storage) { - Platal::assert(in_array($storage, self::get_allowed_storages($user))); + Platal::assert(in_array($storage, self::get_allowed_storages($user)), 'Unknown storage.'); if (!self::is_active_storage($user, $storage)) { global $globals;