Happy New Year!!!
[platal.git] / include / massmailer.inc.php
CommitLineData
16cd99fb 1<?php
2/***************************************************************************
9f5bd98e 3 * Copyright (C) 2003-2010 Polytechnique.org *
16cd99fb 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
9da70671
SJ
22// {{{ class MailNotFound
23
24class MailNotFound extends Exception {
25}
26
27// }}}
28
16cd99fb 29// {{{ class MassMailer
30
31abstract class MassMailer
32{
33 private $_tpl;
34 private $_css;
35 private $_prefix;
36
37 public $_id;
38 public $_shortname;
39 public $_title;
40 public $_title_mail;
41
42 public $_head;
43
fc9d9368 44 protected $_table;
45 protected $_subscriptionTable;
46
47 function __construct($tpl, $css, $prefix, $tbl, $stbl)
16cd99fb 48 {
49 $this->_tpl = $tpl;
50 $this->_css = $css;
51 $this->_prefix = $prefix;
fc9d9368 52 $this->_table = $tbl;
53 $this->_subscriptionTable = $stbl;
16cd99fb 54 }
55
56 public function id()
57 {
58 return is_null($this->_shortname) ? $this->_id : $this->_shortname;
59 }
60
fc9d9368 61 private function selectId($where)
62 {
63 $res = XDB::query("SELECT IF (n.short_name IS NULL, n.id, n.short_name)
64 FROM {$this->_table} AS n
65 WHERE n.bits != 'new' AND {$where}
eaf30d86 66 LIMIT 1");
fc9d9368 67 if ($res->numRows() != 1) {
68 return null;
69 }
70 return $res->fetchOneCell();
71 }
72
73 public function prev()
74 {
75 static $val;
76 if (!isset($val)) {
77 $val = $this->selectId("n.id < {$this->_id} ORDER BY n.id DESC");
78 }
79 return $val;
80 }
81
82 public function next()
83 {
84 static $val;
85 if (!isset($val)) {
86 $val = $this->selectId("n.id > {$this->_id} ORDER BY n.id");
87 }
88 return $val;
89 }
90
91 public function last()
92 {
93 static $val;
94 if (!isset($val)) {
95 $res = XDB::query("SELECT MAX(n.id)
96 FROM {$this->_table} AS n
97 WHERE n.bits != 'new' AND n.id > {?}",
98 $this->_id);
99 if ($res->numRows() != 1) {
100 $val = null;
101 } else {
102 $val = $res->fetchOneCell();
103 }
104 }
105 return $val;
106 }
107
16cd99fb 108 public function title($mail = false)
109 {
110 return $mail ? $this->_title_mail : $this->_title;
111 }
112
113 public function head($prenom = null, $nom = null, $sexe = null, $type = 'text')
114 {
115 if (is_null($prenom)) {
eaf30d86 116 return $this->_head;
16cd99fb 117 } else {
118 $head = $this->_head;
a7de4ef7 119 $head = str_replace('<cher>', $sexe ? 'Chère' : 'Cher', $head);
16cd99fb 120 $head = str_replace('<prenom>', $prenom, $head);
121 $head = str_replace('<nom>', $nom, $head);
8da0d3c1 122 return format_text($head, $type, 2, 64);
16cd99fb 123 }
124 }
125
126 public function css(&$page = null)
127 {
128 if (!is_null($page)) {
129 $page->addCssLink($this->_css);
130 return true;
131 } else {
132 $css = file_get_contents(dirname(__FILE__) . '/../htdocs/css/' . $this->_css);
a14159bf 133 return preg_replace('@/\*.*?\*/@us', '', $css);
16cd99fb 134 }
135 }
136
137 public function toText(&$page, $prenom, $nom, $sexe)
138 {
139 $this->css($page);
140 $page->assign('is_mail', false);
3ad44e08 141 $page->assign('mail_part', 'text');
16cd99fb 142 $page->assign('prenom', $prenom);
143 $page->assign('nom', $nom);
144 $page->assign('sexe', $sexe);
145 $this->assignData($page);
146 }
147
148 public function toHtml(&$page, $prenom, $nom, $sexe)
149 {
150 $this->css($page);
151 $page->assign('prefix', $this->_prefix . '/' . $this->id());
152 $page->assign('is_mail', false);
3ad44e08 153 $page->assign('mail_part', 'html');
16cd99fb 154 $page->assign('prenom', $prenom);
155 $page->assign('nom', $nom);
156 $page->assign('sexe', $sexe);
157 $this->assignData($page);
158 }
159
39337e2d
FB
160 private function createHash($line, $key = null)
161 {
162 $hash = implode(time(), $line) . rand();
163 $hash = md5($hash);
164 return $hash;
165 }
166
74f583b3 167 public function sendTo($hruid, $email, $prenom, $nom, $sexe, $html, $hash = 0)
16cd99fb 168 {
74f583b3
VZ
169 // If $email is not a real email address, tries to compute it up from
170 // the hruid. Otherwise, we suppose that caller will have used a valid
171 // and canonical email address.
172 if (strpos($email, '@') === false) {
173 if (!($user = User::getSilent($email))) {
174 Platal::page()->trigError("'$email' is neither a valid email address nor a valid login; did not send the email.");
175 }
176 $email = $user->bestEmail();
9833e186 177 }
39337e2d 178
74f583b3
VZ
179 if ($hruid && (is_null($hash) || $hash == 0)) {
180 $hash = $this->createHash(array($email, $prenom, $nom, $sexe, $html, rand(), "X.org rulez"));
39337e2d 181 XDB::query("UPDATE {$this->_subscriptionTable} as ni
74f583b3 182 INNER JOIN auth_user_md5 AS u USING (user_id)
39337e2d 183 SET ni.hash = {?}
74f583b3
VZ
184 WHERE ni.user_id != 0 AND u.hruid = {?}",
185 $hash, $hruid);
39337e2d 186 }
16cd99fb 187
188 $mailer = new PlMailer($this->_tpl);
189 $this->assignData($mailer);
190 $mailer->assign('is_mail', true);
191 $mailer->assign('prenom', $prenom);
192 $mailer->assign('nom', $nom);
193 $mailer->assign('sexe', $sexe);
194 $mailer->assign('prefix', null);
a0f05027 195 $mailer->assign('hash', $hash);
74f583b3
VZ
196 $mailer->assign('email', $email);
197 $mailer->assign('alias', $hruid);
198 $mailer->addTo("\"$prenom $nom\" <$email>");
16cd99fb 199 $mailer->send($html);
200 }
201
a0f05027 202 protected function getAllRecipients()
203 {
b2192733 204 global $globals;
74f583b3 205 return "SELECT u.user_id, u.hruid, CONCAT(a.alias, '@{$globals->mail->domain}'),
a0f05027 206 u.prenom, IF(u.nom_usage='', u.nom, u.nom_usage),
207 FIND_IN_SET('femme', u.flags),
39337e2d 208 q.core_mail_fmt AS pref, ni.hash AS hash
fc9d9368 209 FROM {$this->_subscriptionTable} AS ni
a0f05027 210 INNER JOIN auth_user_md5 AS u USING(user_id)
211 INNER JOIN auth_user_quick AS q ON(q.user_id = u.user_id)
212 INNER JOIN aliases AS a ON(u.user_id=a.id AND FIND_IN_SET('bestalias',a.flags))
213 LEFT JOIN emails AS e ON(e.uid=u.user_id AND e.flags='active')
c3b45f48
VZ
214 WHERE ni.last < {?} AND ({$this->subscriptionWhere()}) AND
215 (e.email IS NOT NULL OR FIND_IN_SET('googleapps', u.mail_storage))
a0f05027 216 GROUP BY u.user_id";
217 }
218
16cd99fb 219 public function sendToAll()
220 {
221 $this->setSent();
a0f05027 222 $query = $this->getAllRecipients() . " LIMIT {?}";
16cd99fb 223 while (true) {
a0f05027 224 $res = XDB::iterRow($query, $this->_id, 60);
16cd99fb 225 if (!$res->total()) {
4e25428d 226 return;
16cd99fb 227 }
228 $sent = array();
74f583b3
VZ
229 while (list($uid, $hruid, $email, $prenom, $nom, $sexe, $fmt, $hash) = $res->next()) {
230 $sent[] = "(user_id='$uid'" . (!$uid ? " AND email='$email')": ')');
231 $this->sendTo($hruid, $email, $prenom, $nom, $sexe, $fmt=='html', $hash);
16cd99fb 232 }
fc9d9368 233 XDB::execute("UPDATE {$this->_subscriptionTable}
16cd99fb 234 SET last = {?}
235 WHERE " . implode(' OR ', $sent), $this->_id);
eaf30d86 236
16cd99fb 237 sleep(60);
238 }
239 }
240
241 abstract protected function assignData(&$smarty);
242 abstract protected function setSent();
243
16cd99fb 244 abstract protected function subscriptionWhere();
245}
246
247// }}}
248// {{{ Functions
249
8da0d3c1 250function format_text($input, $format, $indent = 0, $width = 68)
251{
252 if ($format == 'text') {
02fdd1c8 253 return MiniWiki::WikiToText($input, true, $indent, $width, "title");
8da0d3c1 254 }
02fdd1c8 255 return MiniWiki::WikiToHTML($input, "title");
8da0d3c1 256}
257
02fdd1c8 258// function enriched_to_text($input,$html=false,$just=false,$indent=0,$width=68)
16cd99fb 259
260// }}}
261
a7de4ef7 262// vim:set et sw=4 sts=4 sws=4 enc=utf-8:
16cd99fb 263?>