Commit | Line | Data |
---|---|---|
0337d704 | 1 | <?php |
2 | /*************************************************************************** | |
ba6ae046 | 3 | * Copyright (C) 2003-2013 Polytechnique.org * |
0337d704 | 4 | * http://opensource.polytechnique.org/ * |
5 | * * | |
6 | * This program is free software; you can redistribute it and/or modify * | |
7 | * it under the terms of the GNU General Public License as published by * | |
8 | * the Free Software Foundation; either version 2 of the License, or * | |
9 | * (at your option) any later version. * | |
10 | * * | |
11 | * This program is distributed in the hope that it will be useful, * | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
14 | * GNU General Public License for more details. * | |
15 | * * | |
16 | * You should have received a copy of the GNU General Public License * | |
17 | * along with this program; if not, write to the Free Software * | |
18 | * Foundation, Inc., * | |
19 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * | |
20 | ***************************************************************************/ | |
21 | ||
b4503762 SJ |
22 | define('SUCCESS', 1); |
23 | define('ERROR_INACTIVE_REDIRECTION', 2); | |
24 | define('ERROR_INVALID_EMAIL', 3); | |
25 | define('ERROR_LOOP_EMAIL', 4); | |
0337d704 | 26 | |
ca6980dc SJ |
27 | // Checks if an email update is required in MLs and aliases. |
28 | // This occurs when the user don't have email permissions and her email has changed. | |
29 | function require_email_update(User $user, $new_email) | |
30 | { | |
31 | Platal::assert(!is_null($user), 'User cannot be null.'); | |
32 | ||
8a41e7f9 SJ |
33 | $is_new = !$user->checkPerms(User::PERM_MAIL) && $new_email != strtolower($user->email); |
34 | if ($new_email && $is_new) { | |
35 | $already = XDB::fetchOneCell('SELECT hruid | |
36 | FROM accounts | |
37 | WHERE email = {?} AND uid != {?}', | |
38 | $new_email, $user->id()); | |
39 | if ($already) { | |
40 | Platal::page()->trigError("L'email ne peut pas être utilisé pour ce compte car il correspond déjà au compte : " | |
41 | . $already . ". Si l'utilisateur courant et cette personne ne sont en fait qu'une " | |
42 | . "seul et même personne, ou en cas de problème, contacter : contact@polytechnique.org"); | |
43 | return false; | |
44 | } | |
45 | } | |
46 | return $is_new; | |
ca6980dc SJ |
47 | } |
48 | ||
7e82b545 | 49 | function format_email_alias($email) |
85ddf64f | 50 | { |
7e82b545 SJ |
51 | if ($user = User::getSilent($email)) { |
52 | return $user->forlifeEmail(); | |
53 | } | |
54 | if (isvalid_email($email)) { | |
55 | return $email; | |
56 | } | |
57 | return null; | |
58 | } | |
59 | ||
60 | function add_to_list_alias($email, $local_part, $domain, $type = 'alias') | |
61 | { | |
62 | $email = format_email_alias($email); | |
63 | if (is_null($email)) { | |
64 | return false; | |
65 | } | |
85ddf64f SJ |
66 | |
67 | XDB::execute('INSERT IGNORE INTO email_virtual (email, domain, redirect, type) | |
68 | SELECT {?}, id, {?}, {?} | |
69 | FROM email_virtual_domains | |
70 | WHERE name = {?}', | |
7e82b545 SJ |
71 | $local_part, $email, $type, $domain); |
72 | return true; | |
85ddf64f SJ |
73 | } |
74 | ||
7e82b545 | 75 | function delete_from_list_alias($email, $local_part, $domain, $type = 'alias') |
85ddf64f | 76 | { |
7e82b545 SJ |
77 | $email = format_email_alias($email); |
78 | if (is_null($email)) { | |
79 | return false; | |
80 | } | |
85ddf64f SJ |
81 | |
82 | XDB::execute('DELETE v | |
83 | FROM email_virtual AS v | |
84 | INNER JOIN email_virtual_domains AS m ON (v.domain = m.id) | |
85 | INNER JOIN email_virtual_domains AS d ON (d.aliasing = m.id) | |
86 | WHERE v.email = {?} AND d.name = {?} AND v.redirect = {?} AND type = {?}', | |
7e82b545 SJ |
87 | $local_part, $domain, $email, $type); |
88 | return true; | |
85ddf64f SJ |
89 | } |
90 | ||
7e82b545 | 91 | function update_list_alias($email, $former_email, $local_part, $domain, $type = 'alias') |
7852229b | 92 | { |
7e82b545 SJ |
93 | $email = format_email_alias($email); |
94 | if (is_null($email)) { | |
95 | return false; | |
96 | } | |
7852229b SJ |
97 | |
98 | XDB::execute('UPDATE email_virtual AS v | |
99 | INNER JOIN email_virtual_domains AS d ON (v.domain = d.id) | |
100 | SET v.redirect = {?} | |
101 | WHERE v.redirect = {?} AND d.name = {?} AND v.email = {?} AND v.type = {?}', | |
7e82b545 SJ |
102 | $email, $former_email, $domain, $local_part, $type); |
103 | return true; | |
7852229b SJ |
104 | } |
105 | ||
ca6980dc SJ |
106 | // Updates an email in all aliases (groups and events). |
107 | function update_alias_user($former_email, $new_email) | |
108 | { | |
109 | XDB::execute('UPDATE email_virtual | |
110 | SET redirect = {?} | |
111 | WHERE redirect = {?} AND (type = \'alias\' OR type = \'event\')', | |
112 | $new_email, $former_email); | |
113 | } | |
114 | ||
85ddf64f SJ |
115 | function list_alias_members($local_part, $domain) |
116 | { | |
117 | $emails = XDB::fetchColumn('SELECT DISTINCT(redirect) | |
118 | FROM email_virtual AS v | |
119 | INNER JOIN email_virtual_domains AS m ON (v.domain = m.id) | |
120 | INNER JOIN email_virtual_domains AS d ON (d.aliasing = m.id) | |
51c2c63a | 121 | WHERE v.email = {?} AND d.name = {?} AND type = \'alias\'', |
85ddf64f SJ |
122 | $local_part, $domain); |
123 | ||
d3a4f32c SJ |
124 | $users = array(); |
125 | $nonusers = array(); | |
85ddf64f | 126 | foreach ($emails as $email) { |
d3a4f32c SJ |
127 | if ($user = User::getSilent($email)) { |
128 | $users[] = $user; | |
129 | } else { | |
130 | $nonusers[] = $email; | |
131 | } | |
85ddf64f SJ |
132 | } |
133 | ||
d3a4f32c SJ |
134 | return array( |
135 | 'users' => $users, | |
136 | 'nonusers' => $nonusers | |
137 | ); | |
85ddf64f SJ |
138 | } |
139 | ||
140 | function delete_list_alias($local_part, $domain) | |
141 | { | |
142 | XDB::execute('DELETE v | |
143 | FROM email_virtual AS v | |
144 | INNER JOIN email_virtual_domains AS m ON (v.domain = m.id) | |
145 | INNER JOIN email_virtual_domains AS d ON (d.aliasing = m.id) | |
51c2c63a | 146 | WHERE v.email = {?} AND d.name = {?} AND type = \'alias\'', |
85ddf64f SJ |
147 | $local_part, $domain); |
148 | } | |
149 | ||
150 | function iterate_list_alias($domain) | |
151 | { | |
152 | return XDB::fetchColumn('SELECT CONCAT(v.email, \'@\', m.name) | |
153 | FROM email_virtual AS v | |
154 | INNER JOIN email_virtual_domains AS m ON (v.domain = m.id) | |
63112e27 | 155 | WHERE m.name = {?} AND v.type = \'alias\' |
85ddf64f SJ |
156 | GROUP BY v.email', |
157 | $domain); | |
158 | } | |
159 | ||
160 | function create_list($local_part, $domain) | |
161 | { | |
162 | global $globals; | |
163 | ||
164 | $redirect = $domain . '_' . $local_part . '+'; | |
165 | foreach(array('post', 'owner', 'admin', 'bounces', 'unsubscribe') as $suffix) { | |
166 | XDB::execute('INSERT IGNORE INTO email_virtual (email, domain, redirect, type) | |
167 | SELECT {?}, id, {?}, \'list\' | |
168 | FROM email_virtual_domains | |
169 | WHERE name = {?}', | |
170 | ($suffix == 'post') ? $local_part : $local_part . '-' . $suffix, | |
171 | $redirect . $suffix . '@' . $globals->lists->redirect_domain, $domain); | |
172 | } | |
173 | } | |
174 | ||
175 | function delete_list($local_part, $domain) | |
176 | { | |
177 | global $globals; | |
178 | ||
179 | $redirect = $domain . '_' . $local_part . '+'; | |
180 | foreach(array('post', 'owner', 'admin', 'bounces', 'unsubscribe') as $suffix) { | |
30e6bbe3 SJ |
181 | XDB::execute('DELETE FROM email_virtual |
182 | WHERE redirect = {?} AND type = \'list\'', | |
85ddf64f SJ |
183 | $redirect . $suffix . '@' . $globals->lists->redirect_domain); |
184 | } | |
185 | } | |
186 | ||
187 | function list_exist($local_part, $domain) | |
188 | { | |
189 | return XDB::fetchOneCell('SELECT COUNT(*) | |
190 | FROM email_virtual AS v | |
191 | INNER JOIN email_virtual_domains AS m ON (v.domain = m.id) | |
192 | INNER JOIN email_virtual_domains AS d ON (m.id = d.aliasing) | |
193 | WHERE v.email = {?} AND d.name = {?}', | |
194 | $local_part, $domain); | |
195 | } | |
196 | ||
a9fd3272 SJ |
197 | // function mark_broken_email() {{{1 |
198 | function mark_broken_email($email, $admin = false) | |
199 | { | |
200 | $email = valide_email($email); | |
201 | if (empty($email) || $email == '@') { | |
202 | return; | |
203 | } | |
204 | ||
a51d0d30 | 205 | $user = XDB::fetchOneAssoc('SELECT r1.uid, a.hruid, a.full_name, r1.broken_level != 0 AS broken, COUNT(r2.uid) AS nb_mails, |
dd092f56 | 206 | s.email AS alias, DATE_ADD(r1.last, INTERVAL 14 DAY) < CURDATE() as notify |
a9fd3272 SJ |
207 | FROM email_redirect_account AS r1 |
208 | INNER JOIN accounts AS a ON (a.uid = r1.uid) | |
209 | INNER JOIN email_source_account AS s ON (a.uid = s.uid AND s.flags = \'bestalias\') | |
210 | LEFT JOIN email_redirect_account AS r2 ON (a.uid = r2.uid AND r1.redirect != r2.redirect AND | |
211 | r2.broken_level = 0 AND r2.flags = \'active\' AND | |
212 | (r2.type = \'smtp\' OR r2.type = \'googleapps\')) | |
213 | WHERE r1.redirect = {?} | |
214 | GROUP BY r1.uid', $email); | |
215 | ||
216 | if ($user) { | |
217 | // Mark address as broken. | |
218 | if (!$user['broken']) { | |
219 | XDB::execute('UPDATE email_redirect_account | |
220 | SET broken_date = NOW(), last = NOW(), broken_level = 1 | |
221 | WHERE redirect = {?}', $email); | |
222 | } elseif ($admin) { | |
223 | XDB::execute('UPDATE email_redirect_account | |
337a6acf | 224 | SET last = CURDATE(), broken_level = broken_level + 1 |
a9fd3272 SJ |
225 | WHERE redirect = {?} AND DATE_ADD(last, INTERVAL 14 DAY) < CURDATE()', |
226 | $email); | |
227 | } else { | |
228 | XDB::execute('UPDATE email_redirect_account | |
229 | SET broken_level = 1 | |
230 | WHERE redirect = {?} AND broken_level = 0', $email); | |
231 | } | |
232 | } | |
233 | ||
234 | return $user; | |
235 | } | |
236 | ||
441c2451 | 237 | // function fix_bestalias() {{{1 |
11ed26e5 VZ |
238 | // Checks for an existing 'bestalias' among the the current user's aliases, and |
239 | // eventually selects a new bestalias when required. | |
26ba053e | 240 | function fix_bestalias(User $user) |
0337d704 | 241 | { |
f067a3d6 SJ |
242 | // First check if the bestalias is properly set. |
243 | $alias_count = XDB::fetchOneCell('SELECT COUNT(*) | |
244 | FROM email_source_account | |
245 | WHERE uid = {?} AND FIND_IN_SET(\'bestalias\', flags) AND expire IS NULL', | |
246 | $user->id()); | |
11ed26e5 | 247 | |
f067a3d6 | 248 | if ($alias_count > 1) { |
b4503762 SJ |
249 | // If too many bestaliases, delete the bestalias flag from all this |
250 | // user's emails (this should never happen). | |
251 | XDB::execute("UPDATE email_source_account | |
252 | SET flags = TRIM(BOTH ',' FROM REPLACE(CONCAT(',', flags, ','), ',bestalias,', ',')) | |
253 | WHERE uid = {?}", | |
254 | $user->id()); | |
255 | } | |
f067a3d6 SJ |
256 | if ($alias_count != 1) { |
257 | // If no bestalias is selected, we choose the shortest email which is not | |
258 | // related to a usage name and contains a '.'. | |
259 | XDB::execute("UPDATE email_source_account | |
260 | SET flags = CONCAT_WS(',', IF(flags = '', NULL, flags), 'bestalias') | |
261 | WHERE uid = {?} AND expire IS NULL | |
262 | ORDER BY NOT FIND_IN_SET('usage', flags), email LIKE '%.%', LENGTH(email) | |
263 | LIMIT 1", | |
264 | $user->id()); | |
265 | } | |
266 | ||
267 | // First check if best_domain is properly set. | |
268 | $domain_count = XDB::fetchOneCell('SELECT COUNT(*) | |
269 | FROM accounts AS a | |
270 | INNER JOIN email_source_account AS s ON (s.uid = a.uid AND FIND_IN_SET(\'bestalias\', s.flags)) | |
271 | INNER JOIN email_virtual_domains AS d ON (d.id = a.best_domain) | |
272 | INNER JOIN email_virtual_domains AS m ON (d.aliasing = m.id) | |
273 | INNER JOIN email_virtual_domains AS v ON (v.aliasing = m.id AND v.id = s.domain) | |
274 | WHERE a.uid = {?} AND (m.name = {?} OR m.name = {?})', | |
275 | $user->id(), $user->mainEmailDomain(), Platal::globals()->mail->alias_dom); | |
276 | ||
277 | if ($domain_count == 0) { | |
278 | XDB::execute('UPDATE accounts AS a | |
279 | INNER JOIN email_source_account AS s ON (s.uid = a.uid AND FIND_IN_SET(\'bestalias\', s.flags)) | |
280 | INNER JOIN email_virtual_domains AS d ON (d.aliasing = s.domain AND (d.name = {?} OR d.name = {?})) | |
281 | SET a.best_domain = d.id | |
282 | WHERE a.uid = {?}', | |
283 | $user->mainEmailDomain(), Platal::globals()->mail->alias_dom, $user->id()); | |
284 | } | |
285 | ||
b4503762 | 286 | |
0337d704 | 287 | } |
288 | ||
441c2451 | 289 | // function valide_email() {{{1 |
11ed26e5 VZ |
290 | // Returns a cleaned-up version of the @p email string. It removes garbage |
291 | // characters, and determines the canonical form (without _ and +) for | |
292 | // Polytechnique.org email addresses. | |
0337d704 | 293 | function valide_email($str) |
294 | { | |
a3a049fc | 295 | global $globals; |
296 | ||
297 | $em = trim(rtrim($str)); | |
298 | $em = str_replace('<', '', $em); | |
299 | $em = str_replace('>', '', $em); | |
97664536 SJ |
300 | if (strpos($em, '@') === false) { |
301 | return; | |
302 | } | |
a3a049fc | 303 | list($ident, $dom) = explode('@', $em); |
f036c896 | 304 | if (User::isMainMailDomain($dom)) { |
a3a049fc | 305 | list($ident1) = explode('_', $ident); |
306 | list($ident) = explode('+', $ident1); | |
307 | } | |
308 | return $ident . '@' . $dom; | |
0337d704 | 309 | } |
310 | ||
c6310567 | 311 | // function isvalid_email_redirection() {{{1 |
b4503762 SJ |
312 | /** Checks if an email is a suitable redirection. |
313 | * @param $email the email to check | |
f4dda5fb | 314 | * @param $user the user asking for the redirection |
c6310567 FB |
315 | * @return BOOL |
316 | */ | |
f4dda5fb | 317 | function isvalid_email_redirection($email, User $user) |
c6310567 | 318 | { |
f4dda5fb BG |
319 | $valid = isvalid_email($email) && User::isForeignEmailAddress($email); |
320 | if (!$user->hasProfile() || ($user->profile()->grad_year > date('Y') - 3)) { | |
321 | return $valid && !preg_match("/@polytechnique\.edu$/", $email); | |
322 | } else { | |
323 | return $valid; | |
324 | } | |
c6310567 FB |
325 | } |
326 | ||
180627f3 | 327 | // function ids_from_mails() {{{1 |
b4503762 SJ |
328 | // Converts an array of emails to an array of email => uid, where email is the |
329 | // given email when we found a matching user. | |
180627f3 | 330 | function ids_from_mails(array $emails) |
1605f171 | 331 | { |
b4503762 SJ |
332 | // Removes duplicates, if any. |
333 | $emails = array_unique($emails); | |
334 | ||
335 | // Formats and splits by domain type (locally managed or external) emails. | |
f036c896 SJ |
336 | $main_domain_emails = array(); |
337 | $aux_domain_emails = array(); | |
338 | $other_emails = array(); | |
1605f171 RB |
339 | foreach ($emails as $email) { |
340 | if (strpos($email, '@') === false) { | |
f036c896 | 341 | $main_domain_emails[] = $email; |
1605f171 | 342 | } else { |
f036c896 SJ |
343 | if (User::isForeignEmailAddress($email)) { |
344 | $other_emails[$email] = strtolower($user . '@' . $domain); | |
345 | } else { | |
346 | list($local_part, $domain) = explode('@', $email); | |
347 | list($local_part) = explode('+', $local_part); | |
348 | list($local_part) = explode('_', $local_part); | |
349 | if (User::isMainMailDomain($domain)) { | |
350 | $main_domain_emails[$email] = strtolower($local_part); | |
351 | } elseif (User::isAliasMailDomain($domain)) { | |
352 | $aux_domain_emails[$email] = strtolower($local_part); | |
353 | } | |
354 | } | |
1605f171 RB |
355 | } |
356 | } | |
180627f3 | 357 | |
b4503762 | 358 | // Retrieves emails from our domains. |
f036c896 SJ |
359 | $main_domain_uids = XDB::fetchAllAssoc('email', |
360 | 'SELECT email, uid | |
361 | FROM email_source_account | |
362 | WHERE email IN {?} AND type != \'alias_aux\'', | |
363 | array_unique($main_domain_emails)); | |
364 | $aux_domain_uids = XDB::fetchAllAssoc('email', | |
365 | 'SELECT email, uid | |
366 | FROM email_source_account | |
367 | WHERE email IN {?} AND type = \'alias_aux\'', | |
368 | array_unique($aux_domain_emails)); | |
1605f171 | 369 | |
b4503762 SJ |
370 | // Retrieves emails from redirections. |
371 | $other_uids = XDB::fetchAllAssoc('redirect', | |
372 | 'SELECT redirect, uid | |
373 | FROM email_redirect_account | |
374 | WHERE redirect IN {?}', | |
375 | array_unique($other_emails)); | |
1605f171 | 376 | |
b4503762 SJ |
377 | // Associates given emails with the corresponding uid. |
378 | $uids = array(); | |
f036c896 SJ |
379 | foreach ($main_domain_emails as $email => $key) { |
380 | $uids[$email] = $main_domain_uids[$key]; | |
381 | } | |
382 | foreach ($aux_domain_emails as $email => $key) { | |
383 | $uids[$email] = $aux_domain_uids[$key]; | |
384 | } | |
385 | foreach ($other_emails as $email => $key) { | |
386 | $uids[$email] = $other_uids[$key]; | |
1605f171 RB |
387 | } |
388 | ||
f036c896 | 389 | return array_unique($uids); |
1605f171 RB |
390 | } |
391 | ||
441c2451 | 392 | // class Bogo {{{1 |
11ed26e5 | 393 | // The Bogo class represents a spam filtering level in plat/al architecture. |
0337d704 | 394 | class Bogo |
395 | { | |
5ad556d3 SJ |
396 | const MAIN_DEFAULT = 'default'; |
397 | const IMAP_DEFAULT = 'let_spams'; | |
398 | ||
1bab8330 | 399 | public static $states = array( |
3b346b99 SJ |
400 | 0 => 'default', |
401 | 1 => 'let_spams', | |
402 | 2 => 'tag_spams', | |
403 | 3 => 'tag_and_drop_spams', | |
404 | 4 => 'drop_spams' | |
405 | ); | |
a3a049fc | 406 | |
12a587df | 407 | private $user; |
3b346b99 SJ |
408 | public $state; |
409 | public $single_state; | |
410 | public $redirections; | |
411 | public $single_redirection; | |
a3a049fc | 412 | |
26ba053e | 413 | public function __construct(User $user) |
0337d704 | 414 | { |
12a587df | 415 | if (!$user) { |
3c1e6a1e | 416 | return; |
417 | } | |
11ed26e5 | 418 | |
12a587df | 419 | $this->user = &$user; |
3b346b99 SJ |
420 | $res = XDB::fetchOneAssoc('SELECT COUNT(DISTINCT(action)) AS action_count, COUNT(redirect) AS redirect_count, action |
421 | FROM email_redirect_account | |
983c2a9a SJ |
422 | WHERE uid = {?} AND (type = \'smtp\' OR type = \'googleapps\') AND flags = \'active\' |
423 | GROUP BY uid', | |
3b346b99 SJ |
424 | $user->id()); |
425 | if ($res['redirect_count'] == 0) { | |
b4503762 | 426 | return; |
3c1e6a1e | 427 | } |
3b346b99 SJ |
428 | |
429 | $this->single_redirection = ($res['redirect_count'] == 1); | |
430 | $this->redirections = XDB::fetchAllAssoc('SELECT IF(type = \'googleapps\', type, redirect) AS redirect, type, action | |
431 | FROM email_redirect_account | |
432 | WHERE uid = {?} AND (type = \'smtp\' OR type = \'googleapps\') | |
433 | ORDER BY type, redirect', | |
434 | $user->id()); | |
435 | ||
436 | foreach ($this->redirections AS &$redirection) { | |
437 | $redirection['filter'] = array_search($redirection['action'], self::$states); | |
438 | } | |
439 | if ($res['action_count'] == 1) { | |
440 | $this->state = array_search($res['action'], self::$states); | |
441 | $this->single_state = true; | |
442 | } else { | |
443 | $this->single_state = $this->state = false; | |
444 | } | |
0337d704 | 445 | } |
446 | ||
3b346b99 | 447 | public function changeAll($state) |
0337d704 | 448 | { |
3b346b99 SJ |
449 | Platal::assert($state >= 0 && $state < count(self::$states), 'Unknown antispam level.'); |
450 | ||
451 | $this->state = $state; | |
b4503762 SJ |
452 | XDB::execute('UPDATE email_redirect_account |
453 | SET action = {?} | |
454 | WHERE uid = {?} AND (type = \'smtp\' OR type = \'googleapps\')', | |
3b346b99 | 455 | self::$states[$this->state], $this->user->id()); |
0337d704 | 456 | } |
457 | ||
3b346b99 | 458 | public function change($redirection, $state) |
612a2d8a | 459 | { |
3b346b99 SJ |
460 | Platal::assert($state >= 0 && $state < count(self::$states), 'Unknown antispam level.'); |
461 | ||
462 | XDB::execute('UPDATE email_redirect_account | |
463 | SET action = {?} | |
464 | WHERE uid = {?} AND (type = {?} OR redirect = {?})', | |
465 | self::$states[$state], $this->user->id(), $redirection, $redirection); | |
612a2d8a | 466 | } |
0337d704 | 467 | } |
468 | ||
441c2451 | 469 | // class Email {{{1 |
11ed26e5 | 470 | // Represents an "email address" used as final recipient for plat/al-managed |
b4503762 SJ |
471 | // addresses. |
472 | class Email | |
0337d704 | 473 | { |
b4503762 SJ |
474 | // Lists fields to load automatically. |
475 | static private $field_names = array('rewrite', 'type', 'action', 'broken_date', 'broken_level', 'last', 'hash', 'allow_rewrite'); | |
476 | ||
477 | // Shortname to realname mapping for known mail storage backends. | |
478 | static private $display_names = array( | |
479 | 'imap' => 'Accès de secours aux emails (IMAP)', | |
480 | 'googleapps' => 'Compte Google Apps', | |
481 | ); | |
482 | static private $storage_domains = array( | |
483 | 'imap' => 'imap', | |
484 | 'googleapps' => 'g' | |
485 | ); | |
486 | ||
487 | private $user; | |
612a2d8a | 488 | |
11ed26e5 | 489 | // Basic email properties; $sufficient indicates if the email can be used as |
b4503762 | 490 | // an unique redirection; $redirect contains the delivery email address. |
e4f549fd | 491 | public $id; |
11ed26e5 VZ |
492 | public $type; |
493 | public $sufficient; | |
612a2d8a | 494 | public $email; |
11ed26e5 | 495 | public $display_email; |
b4503762 SJ |
496 | public $domain; |
497 | public $action; | |
1bab8330 | 498 | public $filter_level; |
11ed26e5 VZ |
499 | |
500 | // Redirection status properties. | |
612a2d8a | 501 | public $active; |
b4503762 | 502 | public $inactive; |
612a2d8a | 503 | public $broken; |
441c2451 | 504 | public $disabled; |
612a2d8a | 505 | public $rewrite; |
3d17e48f FB |
506 | public $allow_rewrite; |
507 | public $hash; | |
11ed26e5 VZ |
508 | |
509 | // Redirection bounces stats. | |
612a2d8a | 510 | public $last; |
b4503762 SJ |
511 | public $broken_level; |
512 | public $broken_date; | |
0337d704 | 513 | |
b4503762 | 514 | public function __construct(User $user, array $row) |
0337d704 | 515 | { |
b4503762 SJ |
516 | foreach (self::$field_names as $field) { |
517 | if (array_key_exists($field, $row)) { | |
518 | $this->$field = $row[$field]; | |
519 | } | |
520 | } | |
521 | $this->email = $row['redirect']; | |
11ed26e5 | 522 | |
b4503762 SJ |
523 | if (array_key_exists($this->type, Email::$display_names)) { |
524 | $this->display_email = self::$display_names[$this->type]; | |
525 | } else { | |
526 | $this->display_email = $this->email; | |
527 | } | |
528 | foreach (array('active', 'inactive', 'broken', 'disabled') as $status) { | |
529 | $this->$status = ($status == $row['flags']); | |
530 | } | |
531 | $this->sufficient = ($this->type == 'smtp' || $this->type == 'googleapps'); | |
1bab8330 | 532 | $this->filter_level = ($this->type == 'imap') ? null : array_search($this->action, Bogo::$states); |
e4f549fd SJ |
533 | if (array_key_exists($this->type , self::$storage_domains)) { |
534 | $this->id = $this->type; | |
535 | } else { | |
105427e9 | 536 | $this->id = str_replace(array('@', '.'), array('_at_', '_dot_'), $this->email); |
e4f549fd | 537 | } |
b4503762 | 538 | $this->user = &$user; |
0337d704 | 539 | } |
540 | ||
b4503762 | 541 | // Activates the email address as a redirection. |
11ed26e5 | 542 | public function activate() |
0337d704 | 543 | { |
468a27eb | 544 | if (!$this->active) { |
35be5845 | 545 | if (in_array($this->type, self::get_allowed_storages($this->user))) { |
5ad556d3 SJ |
546 | self::activate_storage($this->user, $this->type, $this->action); |
547 | } else { | |
548 | XDB::execute('UPDATE email_redirect_account | |
549 | SET broken_level = IF(flags = \'broken\', broken_level - 1, broken_level), flags = \'active\' | |
550 | WHERE uid = {?} AND redirect = {?}', | |
551 | $this->user->id(), $this->email); | |
552 | } | |
b4503762 | 553 | S::logger()->log('email_on', $this->email . ($this->user->id() != S::v('uid') ? "(admin on {$this->user->login()})" : '')); |
468a27eb SJ |
554 | $this->disabled = false; |
555 | $this->broken = false; | |
b4503762 SJ |
556 | $this->inactive = false; |
557 | $this->active = true; | |
0337d704 | 558 | } |
559 | } | |
560 | ||
b4503762 | 561 | // Deactivates the email address as a redirection. |
11ed26e5 | 562 | public function deactivate() |
0337d704 | 563 | { |
0337d704 | 564 | if ($this->active) { |
35be5845 | 565 | if (in_array($this->type, self::get_allowed_storages($this->user))) { |
5ad556d3 SJ |
566 | self::deactivate_storage($this->user, $this->type); |
567 | } else { | |
568 | XDB::execute('UPDATE email_redirect_account | |
569 | SET flags = \'inactive\' | |
570 | WHERE uid = {?} AND redirect = {?}', | |
571 | $this->user->id(), $this->email); | |
572 | } | |
b4503762 SJ |
573 | S::logger()->log('email_off', $this->email . ($this->user->id() != S::v('uid') ? "(admin on {$this->user->login()})" : "") ); |
574 | $this->inactive = true; | |
575 | $this->active = false; | |
0337d704 | 576 | } |
577 | } | |
612a2d8a | 578 | |
0337d704 | 579 | |
b4503762 | 580 | // Sets the rewrite rule for the given address. |
11ed26e5 | 581 | public function set_rewrite($rewrite) |
0337d704 | 582 | { |
b4503762 | 583 | if ($this->type != 'smtp' || $this->rewrite == $rewrite) { |
0337d704 | 584 | return; |
585 | } | |
11ed26e5 VZ |
586 | if (!$rewrite || !isvalid_email($rewrite)) { |
587 | $rewrite = ''; | |
12acff5d | 588 | } |
b4503762 SJ |
589 | XDB::execute('UPDATE email_redirect_account |
590 | SET rewrite = {?} | |
591 | WHERE uid = {?} AND redirect = {?} AND type = \'smtp\'', | |
592 | $rewrite, $this->user->id(), $this->email); | |
11ed26e5 | 593 | $this->rewrite = $rewrite; |
3d17e48f FB |
594 | if (!$this->allow_rewrite) { |
595 | global $globals; | |
596 | if (empty($this->hash)) { | |
597 | $this->hash = rand_url_id(); | |
b4503762 SJ |
598 | XDB::execute('UPDATE email_redirect_account |
599 | SET hash = {?} | |
600 | WHERE uid = {?} AND redirect = {?} AND type = \'smtp\'', | |
601 | $this->hash, $this->user->id(), $this->email); | |
3d17e48f | 602 | } |
3d17e48f FB |
603 | $mail = new PlMailer('emails/rewrite-in.mail.tpl'); |
604 | $mail->assign('mail', $this); | |
21c7c593 | 605 | $mail->assign('user', $this->user); |
3d17e48f | 606 | $mail->assign('baseurl', $globals->baseurl); |
c66de9a0 FB |
607 | $mail->assign('sitename', $globals->core->sitename); |
608 | $mail->assign('to', $this->email); | |
21c7c593 | 609 | $mail->send($this->user->isEmailFormatHtml()); |
3d17e48f | 610 | } |
0337d704 | 611 | } |
612 | ||
441c2451 | 613 | |
b4503762 | 614 | // Resets the error counts associated with the redirection. |
11ed26e5 | 615 | public function clean_errors() |
441c2451 | 616 | { |
b4503762 SJ |
617 | if ($this->type != 'smtp') { |
618 | return; | |
619 | } | |
dd70cd28 | 620 | if (!S::admin()) { |
441c2451 | 621 | return false; |
622 | } | |
b4503762 SJ |
623 | $this->broken = 0; |
624 | $this->broken_level = 0; | |
625 | $this->last = 0; | |
626 | return XDB::execute('UPDATE email_redirect_account | |
627 | SET broken_level = 0, broken_date = 0, last = 0 | |
628 | WHERE uid = {?} AND redirect = {?} AND type = \'smtp\'', | |
12a587df | 629 | $this->user->id(), $this->email); |
11ed26e5 VZ |
630 | } |
631 | ||
11ed26e5 | 632 | |
b4503762 SJ |
633 | // Email backend capabilities ('rewrite' refers to From: rewrite for mails |
634 | // forwarded by Polytechnique.org's MXs; 'removable' indicates if the email | |
635 | // can be definitively removed; 'disable' indicates if the email has a third | |
636 | // status 'disabled' in addition to 'active' and 'inactive'). | |
11ed26e5 VZ |
637 | public function has_rewrite() |
638 | { | |
b4503762 | 639 | return ($this->type == 'smtp'); |
11ed26e5 VZ |
640 | } |
641 | ||
11ed26e5 VZ |
642 | public function is_removable() |
643 | { | |
b4503762 | 644 | return ($this->type == 'smtp'); |
11ed26e5 VZ |
645 | } |
646 | ||
11ed26e5 VZ |
647 | public function has_disable() |
648 | { | |
649 | return true; | |
441c2451 | 650 | } |
afde0a3a | 651 | |
b4503762 | 652 | public function is_redirection() |
afde0a3a | 653 | { |
b4503762 | 654 | return ($this->type == 'smtp'); |
afde0a3a VZ |
655 | } |
656 | ||
657 | // Returns the list of allowed storages for the @p user. | |
5ad556d3 | 658 | static public function get_allowed_storages(User $user) |
afde0a3a VZ |
659 | { |
660 | global $globals; | |
661 | $storages = array(); | |
662 | ||
663 | // Google Apps storage is available for users with valid Google Apps account. | |
664 | require_once 'googleapps.inc.php'; | |
d058a285 SJ |
665 | if ($user->checkPerms('gapps') && |
666 | $globals->mailstorage->googleapps_domain && | |
12a587df | 667 | GoogleAppsAccount::account_status($user->id()) == 'active') { |
afde0a3a VZ |
668 | $storages[] = 'googleapps'; |
669 | } | |
670 | ||
671 | // IMAP storage is always visible to administrators, and is allowed for | |
672 | // everyone when the service is marked as 'active'. | |
dd70cd28 | 673 | if ($globals->mailstorage->imap_active || S::admin()) { |
afde0a3a VZ |
674 | $storages[] = 'imap'; |
675 | } | |
676 | ||
677 | return $storages; | |
678 | } | |
679 | ||
5ad556d3 SJ |
680 | static public function make_storage_redirection(User $user, $storage) |
681 | { | |
682 | return $user->hruid . '@' . self::$storage_domains[$storage] . '.' . Platal::globals()->mail->domain; | |
683 | } | |
684 | ||
685 | static public function activate_storage(User $user, $storage, $action = null) | |
afde0a3a | 686 | { |
9dd0544e | 687 | Platal::assert(in_array($storage, self::get_allowed_storages($user)), 'Unknown storage.'); |
afde0a3a | 688 | |
5ad556d3 SJ |
689 | // We first need to retrieve the value for the antispam filter if not |
690 | // provided: it is either the user's redirections common value, or if | |
691 | // they differ, our default value. | |
692 | if (is_null($action)) { | |
693 | $bogo = new Bogo($user); | |
694 | $action = ($bogo->single_state ? Bogo::$states[$bogo->state] : Bogo::MAIN_DEFAULT); | |
695 | } | |
b4503762 | 696 | |
5ad556d3 SJ |
697 | if (!self::is_active_storage($user, $storage)) { |
698 | XDB::execute('INSERT INTO email_redirect_account (uid, type, action, redirect, flags) | |
699 | VALUES ({?}, {?}, {?}, {?}, \'active\')', | |
700 | $user->id(), $storage, $action, self::make_storage_redirection($user, $storage)); | |
b4503762 | 701 | } |
afde0a3a VZ |
702 | } |
703 | ||
b4503762 | 704 | static public function deactivate_storage(User $user, $storage) |
afde0a3a | 705 | { |
5ad556d3 | 706 | if (in_array($storage, self::get_allowed_storages($user))) { |
b4503762 SJ |
707 | XDB::execute('DELETE FROM email_redirect_account |
708 | WHERE uid = {?} AND type = {?}', | |
709 | $user->id(), $storage); | |
710 | } | |
afde0a3a VZ |
711 | } |
712 | ||
b4503762 | 713 | static public function is_active_storage(User $user, $storage) |
afde0a3a | 714 | { |
5ad556d3 | 715 | if (!in_array($storage, self::get_allowed_storages($user))) { |
b4503762 | 716 | return false; |
afde0a3a | 717 | } |
b4503762 SJ |
718 | $res = XDB::fetchOneCell('SELECT COUNT(*) |
719 | FROM email_redirect_account | |
f0a52f1b | 720 | WHERE uid = {?} AND type = {?} AND flags = \'active\'', |
b4503762 SJ |
721 | $user->id(), $storage); |
722 | return !is_null($res) && $res > 0; | |
afde0a3a | 723 | } |
afde0a3a | 724 | } |
441c2451 | 725 | // class Redirect {{{1 |
11ed26e5 VZ |
726 | // Redirect is a placeholder class for an user's active redirections (third-party |
727 | // redirection email, or Polytechnique.org mail storages). | |
0337d704 | 728 | class Redirect |
729 | { | |
b4503762 | 730 | private $flags = 'active'; |
12a587df | 731 | private $user; |
612a2d8a | 732 | |
733 | public $emails; | |
0337d704 | 734 | |
26ba053e | 735 | public function __construct(User $user) |
0337d704 | 736 | { |
12a587df | 737 | $this->user = &$user; |
11ed26e5 | 738 | |
afde0a3a | 739 | // Adds third-party email redirections. |
b4503762 SJ |
740 | $res = XDB::iterator('SELECT redirect, rewrite, type, action, broken_date, broken_level, last, flags, hash, allow_rewrite |
741 | FROM email_redirect_account | |
742 | WHERE uid = {?} AND type != \'homonym\'', | |
743 | $user->id()); | |
744 | $this->emails = array(); | |
0337d704 | 745 | while ($row = $res->next()) { |
b4503762 | 746 | $this->emails[] = new Email($user, $row); |
afde0a3a | 747 | } |
5ad556d3 SJ |
748 | |
749 | if ($storages = Email::get_allowed_storages($user)) { | |
750 | // We first need to retrieve the value for the antispam filter: it is | |
751 | // either the user's redirections common value, or if they differ, our | |
752 | // default value. | |
753 | $bogo = new Bogo($user); | |
754 | $filter = ($bogo->single_state ? Bogo::$states[$bogo->state] : Bogo::MAIN_DEFAULT); | |
755 | ||
756 | foreach ($storages as $storage) { | |
757 | if (!Email::is_active_storage($user, $storage)) { | |
758 | $this->emails[] = new Email($user, array( | |
759 | 'redirect' => Email::make_storage_redirection($user, $storage), | |
760 | 'rewrite' => '', | |
761 | 'type' => $storage, | |
762 | 'action' => $filter, | |
763 | 'broken_date' => 0, | |
764 | 'broken_level' => '0000-00-00', | |
765 | 'last' => '0000-00-00', | |
766 | 'flags' => 'inactive', | |
767 | 'hash' => '', | |
768 | 'allow_rewrite' => 0)); | |
769 | } | |
770 | } | |
771 | } | |
0337d704 | 772 | } |
773 | ||
612a2d8a | 774 | public function other_active($email) |
0337d704 | 775 | { |
776 | foreach ($this->emails as $mail) { | |
11ed26e5 | 777 | if ($mail->email != $email && $mail->active && $mail->sufficient) { |
0337d704 | 778 | return true; |
779 | } | |
780 | } | |
781 | return false; | |
782 | } | |
783 | ||
612a2d8a | 784 | public function delete_email($email) |
0337d704 | 785 | { |
0337d704 | 786 | if (!$this->other_active($email)) { |
787 | return ERROR_INACTIVE_REDIRECTION; | |
788 | } | |
b4503762 SJ |
789 | XDB::execute('DELETE FROM email_redirect_account |
790 | WHERE uid = {?} AND redirect = {?} AND type != \'homonym\'', | |
791 | $this->user->id(), $email); | |
12a587df | 792 | S::logger()->log('email_del', $email . ($this->user->id() != S::v('uid') ? " (admin on {$this->user->login()})" : "")); |
11ed26e5 VZ |
793 | foreach ($this->emails as $i => $mail) { |
794 | if ($email == $mail->email) { | |
0337d704 | 795 | unset($this->emails[$i]); |
796 | } | |
3c1e6a1e | 797 | } |
ccdbc270 | 798 | check_redirect($this); |
24e8f53b | 799 | $this->update_imap(); |
0337d704 | 800 | return SUCCESS; |
801 | } | |
802 | ||
612a2d8a | 803 | public function add_email($email) |
0337d704 | 804 | { |
0337d704 | 805 | $email_stripped = strtolower(trim($email)); |
806 | if (!isvalid_email($email_stripped)) { | |
807 | return ERROR_INVALID_EMAIL; | |
808 | } | |
f4dda5fb | 809 | if (!isvalid_email_redirection($email_stripped, $this->user)) { |
0337d704 | 810 | return ERROR_LOOP_EMAIL; |
811 | } | |
1745c7c8 SJ |
812 | // We first need to retrieve the value for the antispam filter: it is |
813 | // either the user's redirections common value, or if they differ, our | |
814 | // default value. | |
815 | $bogo = new Bogo($this->user); | |
5ad556d3 | 816 | $filter = ($bogo->single_state ? Bogo::$states[$bogo->state] : Bogo::MAIN_DEFAULT); |
00ba8a74 | 817 | // If the email was already present for this user, we reset it to the default values, we thus use REPLACE INTO. |
1745c7c8 SJ |
818 | XDB::execute('REPLACE INTO email_redirect_account (uid, redirect, flags, action) |
819 | VALUES ({?}, {?}, \'active\', {?})', | |
820 | $this->user->id(), $email, $filter); | |
db05227f | 821 | // Replace this email by forlife email, if present in aliases and MLs. |
a2966640 | 822 | $listClient = new MMList(S::user()); |
db05227f SJ |
823 | $listClient->change_user_email($email, $this->user->forlifeEmail()); |
824 | update_alias_user($email, $this->user->forlifeEmail()); | |
3c1e6a1e | 825 | if ($logger = S::v('log', null)) { // may be absent --> step4.php |
12a587df | 826 | S::logger()->log('email_add', $email . ($this->user->id() != S::v('uid') ? " (admin on {$this->user->login()})" : "")); |
0337d704 | 827 | } |
3c1e6a1e | 828 | foreach ($this->emails as $mail) { |
829 | if ($mail->email == $email_stripped) { | |
0337d704 | 830 | return SUCCESS; |
831 | } | |
3c1e6a1e | 832 | } |
b4503762 SJ |
833 | $this->emails[] = new Email($this->user, array( |
834 | 'redirect' => $email, | |
835 | 'rewrite' => '', | |
836 | 'type' => 'smtp', | |
1745c7c8 | 837 | 'action' => $filter, |
b4503762 SJ |
838 | 'broken_date' => '0000-00-00', |
839 | 'broken_level' => 0, | |
840 | 'last' => '0000-00-00', | |
841 | 'flags' => 'active', | |
842 | 'hash' => null, | |
843 | 'allow_rewrite' => 0 | |
844 | )); | |
ca6d07f4 | 845 | |
846 | // security stuff | |
12a587df | 847 | check_email($email, "Ajout d'une adresse surveillée aux redirections de " . $this->user->login()); |
ccdbc270 | 848 | check_redirect($this); |
24e8f53b | 849 | $this->update_imap(); |
0337d704 | 850 | return SUCCESS; |
851 | } | |
852 | ||
612a2d8a | 853 | public function modify_email($emails_actifs, $emails_rewrite) |
0337d704 | 854 | { |
b4503762 SJ |
855 | foreach ($this->emails as &$email) { |
856 | if (in_array($email->email, $emails_actifs)) { | |
857 | $email->activate(); | |
3c1e6a1e | 858 | } else { |
b4503762 | 859 | $email->deactivate(); |
3c1e6a1e | 860 | } |
b4503762 | 861 | $email->set_rewrite($emails_rewrite[$email->email]); |
0337d704 | 862 | } |
ccdbc270 | 863 | check_redirect($this); |
24e8f53b | 864 | $this->update_imap(); |
b4503762 | 865 | return SUCCESS; |
0337d704 | 866 | } |
867 | ||
eaf30d86 | 868 | public function modify_one_email($email, $activate) |
ccdbc270 | 869 | { |
b7582015 | 870 | $allinactive = true; |
871 | $thisone = false; | |
8ffa657a | 872 | foreach ($this->emails as $i=>$mail) { |
873 | if ($mail->email == $email) { | |
b7582015 | 874 | $thisone = $i; |
8ffa657a | 875 | } |
11ed26e5 | 876 | $allinactive &= !$mail->active || !$mail->sufficient || $mail->email == $email; |
8ffa657a | 877 | } |
b7582015 | 878 | if ($thisone === false) { |
879 | return ERROR_INVALID_EMAIL; | |
880 | } | |
ccdbc270 | 881 | if ($allinactive || $activate) { |
11ed26e5 | 882 | $this->emails[$thisone]->activate(); |
ccdbc270 | 883 | } else { |
11ed26e5 | 884 | $this->emails[$thisone]->deactivate(); |
ccdbc270 | 885 | } |
886 | check_redirect($this); | |
24e8f53b | 887 | $this->update_imap(); |
b7582015 | 888 | if ($allinactive && !$activate) { |
889 | return ERROR_INACTIVE_REDIRECTION; | |
eaf30d86 | 890 | } |
b4503762 | 891 | return SUCCESS; |
8ffa657a | 892 | } |
893 | ||
612a2d8a | 894 | public function modify_one_email_redirect($email, $redirect) |
895 | { | |
441c2451 | 896 | foreach ($this->emails as &$mail) { |
612a2d8a | 897 | if ($mail->email == $email) { |
11ed26e5 | 898 | $mail->set_rewrite($redirect); |
ccdbc270 | 899 | check_redirect($this); |
24e8f53b | 900 | $this->update_imap(); |
ccdbc270 | 901 | return; |
612a2d8a | 902 | } |
903 | } | |
904 | } | |
441c2451 | 905 | |
11ed26e5 | 906 | public function clean_errors($email) |
441c2451 | 907 | { |
908 | foreach ($this->emails as &$mail) { | |
909 | if ($mail->email == $email) { | |
e1547442 | 910 | check_redirect($this); |
24e8f53b | 911 | $this->update_imap(); |
11ed26e5 | 912 | return $mail->clean_errors(); |
441c2451 | 913 | } |
914 | } | |
915 | return false; | |
916 | } | |
917 | ||
441c2451 | 918 | public function disable() |
919 | { | |
b4503762 | 920 | XDB::execute("UPDATE email_redirect_account |
441c2451 | 921 | SET flags = 'disable' |
20398e42 | 922 | WHERE flags = 'active' AND uid = {?}", $this->user->id()); |
441c2451 | 923 | foreach ($this->emails as &$mail) { |
11ed26e5 | 924 | if ($mail->active && $mail->has_disable()) { |
441c2451 | 925 | $mail->disabled = true; |
926 | $mail->active = false; | |
927 | } | |
928 | } | |
e1547442 | 929 | check_redirect($this); |
24e8f53b | 930 | $this->update_imap(); |
441c2451 | 931 | } |
932 | ||
441c2451 | 933 | public function enable() |
934 | { | |
b4503762 | 935 | XDB::execute("UPDATE email_redirect_account |
441c2451 | 936 | SET flags = 'active' |
20398e42 | 937 | WHERE flags = 'disable' AND uid = {?}", $this->user->id()); |
441c2451 | 938 | foreach ($this->emails as &$mail) { |
939 | if ($mail->disabled) { | |
441c2451 | 940 | $mail->disabled = false; |
b4503762 | 941 | $mail->active = true; |
441c2451 | 942 | } |
e1547442 | 943 | check_redirect($this); |
441c2451 | 944 | } |
24e8f53b | 945 | $this->update_imap(); |
441c2451 | 946 | } |
947 | ||
612a2d8a | 948 | public function get_broken_mx() |
ccdbc270 | 949 | { |
3083bd93 | 950 | $res = XDB::query("SELECT host, text |
8af1d78f FB |
951 | FROM mx_watch |
952 | WHERE state != 'ok'"); | |
120bd636 | 953 | if (!$res->numRows()) { |
ccdbc270 | 954 | return array(); |
955 | } | |
c754cf5b | 956 | $mxs = $res->fetchAllAssoc(); |
ccdbc270 | 957 | $mails = array(); |
958 | foreach ($this->emails as &$mail) { | |
11ed26e5 | 959 | if ($mail->active && strstr($mail->email, '@') !== false) { |
ccdbc270 | 960 | list(,$domain) = explode('@', $mail->email); |
961 | getmxrr($domain, $lcl_mxs); | |
962 | if (empty($lcl_mxs)) { | |
963 | $lcl_mxs = array($domain); | |
964 | } | |
965 | $broken = false; | |
966 | foreach ($mxs as &$mx) { | |
967 | foreach ($lcl_mxs as $lcl) { | |
c754cf5b | 968 | if (fnmatch($mx['host'], $lcl)) { |
ccdbc270 | 969 | $broken = $mx['text']; |
970 | break; | |
971 | } | |
972 | } | |
973 | if ($broken) { | |
3083bd93 | 974 | $mails[] = array('mail' => $mail->email, 'text' => $broken); |
f653ff3d | 975 | break; |
ccdbc270 | 976 | } |
977 | } | |
978 | } | |
979 | } | |
980 | return $mails; | |
981 | } | |
e97e9b8f | 982 | |
e97e9b8f VZ |
983 | public function active_emails() |
984 | { | |
985 | $emails = array(); | |
986 | foreach ($this->emails as $mail) { | |
987 | if ($mail->active) { | |
988 | $emails[] = $mail; | |
989 | } | |
990 | } | |
991 | return $emails; | |
992 | } | |
45282934 | 993 | |
45282934 VZ |
994 | public function get_uid() |
995 | { | |
12a587df | 996 | return $this->user->id(); |
45282934 | 997 | } |
24e8f53b SJ |
998 | |
999 | private function update_imap() | |
1000 | { | |
1001 | // Imaps must bounce if and only if the user has no active redirection. | |
1002 | if (!$this->other_active('')) { | |
1003 | XDB::execute('UPDATE email_redirect_account | |
1004 | SET action = \'imap_and_bounce\' | |
1005 | WHERE type = \'imap\' AND uid = {?}', | |
1006 | $this->user->id()); | |
1007 | } else { | |
1008 | XDB::execute('UPDATE email_redirect_account | |
1009 | SET action = \'let_spams\' | |
1010 | WHERE type = \'imap\' AND uid = {?}', | |
1011 | $this->user->id()); | |
1012 | } | |
1013 | } | |
0337d704 | 1014 | } |
1015 | ||
a7de4ef7 | 1016 | // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8: |
0337d704 | 1017 | ?> |