+ XDB::iterator('SELECT a.uid, a.hruid, pd.promo
+ FROM accounts AS a
+ INNER JOIN account_types AS at ON (a.type = at.type)
+ LEFT JOIN email_redirect_account AS er ON (er.uid = a.uid AND er.flags = \'active\' AND er.broken_level < 3
+ AND er.type != \'imap\' AND er.type != \'homonym\')
+ LEFT JOIN account_profiles AS ap ON (ap.uid = a.uid AND FIND_IN_SET(\'owner\', ap.perms))
+ LEFT JOIN profile_display AS pd ON (ap.pid = pd.pid)
+ WHERE a.state = \'active\' AND er.redirect IS NULL AND FIND_IN_SET(\'mail\', at.perms)
+ GROUP BY a.uid
+ ORDER BY pd.promo, a.hruid'));
+ }
+
+ function handler_broken_addr($page)
+ {
+ require_once 'emails.inc.php';
+ $page->changeTpl('emails/broken_addr.tpl');
+
+ if (Env::has('sort_broken')) {
+ S::assert_xsrf_token();
+
+ $list = trim(Env::v('list'));
+ if ($list == '') {
+ $page->trigError('La liste est vide.');
+ } else {
+ $valid_emails = array();
+ $invalid_emails = array();
+ $broken_list = explode("\n", $list);
+ sort($broken_list);
+ foreach ($broken_list as $orig_email) {
+ $orig_email = trim($orig_email);
+ if ($orig_email != '') {
+ $email = valide_email($orig_email);
+ if (empty($email) || $email == '@') {
+ $invalid_emails[] = trim($orig_email) . ': invalid email';
+ } elseif (!in_array($email, $valid_emails)) {
+ $nb = XDB::fetchOneCell('SELECT COUNT(*)
+ FROM email_redirect_account
+ WHERE redirect = {?}', $email);
+ if ($nb > 0) {
+ $valid_emails[] = $email;
+ } else {
+ $invalid_emails[] = $orig_email . ': no such redirection';
+ }
+ }
+ }
+ }
+
+ $page->assign('valid_emails', $valid_emails);
+ $page->assign('invalid_emails', $invalid_emails);
+ }
+ }
+
+ if (Env::has('process_broken')) {
+ S::assert_xsrf_token();
+
+ $list = trim(Env::v('list'));
+ if ($list == '') {
+ $page->trigError('La liste est vide.');
+ } else {
+ $broken_user_list = array();
+ $broken_list = explode("\n", $list);
+ sort($broken_list);
+
+ foreach ($broken_list as $email) {
+ if ($user = mark_broken_email($email, true)) {
+ if ($user['nb_mails'] > 0) {
+ $mail = new PlMailer('emails/broken.mail.tpl');
+ $mail->addTo($user);
+ $mail->assign('user', $user);
+ $mail->assign('email', $email);
+ $mail->send();
+ }
+
+ if (!isset($broken_user_list[$user['alias']])) {
+ $broken_user_list[$user['alias']] = array($email);
+ } else {
+ $broken_user_list[$user['alias']][] = $email;
+ }
+ }
+ }
+
+ XDB::execute('UPDATE email_redirect_account
+ SET broken_level = broken_level - 1
+ WHERE flags = \'active\' AND broken_level > 1
+ AND DATE_ADD(last, INTERVAL 1 MONTH) < CURDATE()');
+ XDB::execute('UPDATE email_redirect_account
+ SET broken_level = 0
+ WHERE flags = \'active\' AND broken_level = 1
+ AND DATE_ADD(last, INTERVAL 1 YEAR) < CURDATE()');
+
+ // Output the list of users with recently broken addresses,
+ // along with the count of valid redirections.
+ require_once 'notifs.inc.php';
+ pl_cached_content_headers('text/x-csv', 1);
+
+ $csv = fopen('php://output', 'w');
+ fputcsv($csv, array('nom', 'promo', 'alias', 'bounce', 'nbmails', 'url', 'corps', 'job', 'networking'), ';');
+ foreach ($broken_user_list as $alias => $mails) {
+ $sel = Xdb::query(
+ 'SELECT a.uid, count(DISTINCT(r.redirect)) AS nb_mails,
+ IFNULL(pd.public_name, a.full_name) AS fullname,
+ IFNULL(pd.promo, 0) AS promo, IFNULL(pce.name, \'Aucun\') AS corps,
+ IFNULL(pje.name, \'Aucun\') AS job, GROUP_CONCAT(pn.address SEPARATOR \', \') AS networking
+ FROM email_source_account AS s
+ INNER JOIN accounts AS a ON (s.uid = a.uid)
+ LEFT JOIN email_redirect_account AS r ON (a.uid = r.uid AND r.broken_level = 0 AND r.flags = \'active\' AND
+ (r.type = \'smtp\' OR r.type = \'googleapps\'))
+ LEFT JOIN account_profiles AS ap ON (a.uid = ap.uid AND FIND_IN_SET(\'owner\', ap.perms))
+ LEFT JOIN profile_display AS pd ON (pd.pid = ap.pid)
+ LEFT JOIN profile_corps AS pc ON (pc.pid = ap.pid)
+ LEFT JOIN profile_corps_enum AS pce ON (pc.current_corpsid = pce.id)
+ LEFT JOIN profile_job AS pj ON (pj.pid = ap.pid)
+ LEFT JOIN profile_job_enum AS pje ON (pj.jobid = pje.id)
+ LEFT JOIN profile_networking AS pn ON (pn.pid = ap.pid)
+ WHERE s.email = {?}
+ GROUP BY a.uid', $alias);
+
+ if ($x = $sel->fetchOneAssoc()) {
+ if ($x['nb_mails'] == 0) {
+ $user = User::getSilentWithUID($x['uid']);
+ $profile = $user->profile();
+ WatchProfileUpdate::register($profile, 'broken');
+ }
+ fputcsv($csv, array($x['fullname'], $x['promo'], $alias,
+ join(',', $mails), $x['nb_mails'],
+ 'https://www.polytechnique.org/marketing/broken/' . $alias,
+ $x['corps'], $x['job'], $x['networking']), ';');
+ }
+ }
+ fclose($csv);
+ exit;
+ }
+ }