wrong ext
[platal.git] / include / massmailer.inc.php
CommitLineData
16cd99fb 1<?php
2/***************************************************************************
3 * Copyright (C) 2003-2007 Polytechnique.org *
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
22require_once("xorg.misc.inc.php");
23
24// {{{ class MassMailer
25
26abstract class MassMailer
27{
28 private $_tpl;
29 private $_css;
30 private $_prefix;
31
32 public $_id;
33 public $_shortname;
34 public $_title;
35 public $_title_mail;
36
37 public $_head;
38
fc9d9368 39 protected $_table;
40 protected $_subscriptionTable;
41
42 function __construct($tpl, $css, $prefix, $tbl, $stbl)
16cd99fb 43 {
44 $this->_tpl = $tpl;
45 $this->_css = $css;
46 $this->_prefix = $prefix;
fc9d9368 47 $this->_table = $tbl;
48 $this->_subscriptionTable = $stbl;
16cd99fb 49 }
50
51 public function id()
52 {
53 return is_null($this->_shortname) ? $this->_id : $this->_shortname;
54 }
55
fc9d9368 56 private function selectId($where)
57 {
58 $res = XDB::query("SELECT IF (n.short_name IS NULL, n.id, n.short_name)
59 FROM {$this->_table} AS n
60 WHERE n.bits != 'new' AND {$where}
61 LIMIT 1");
62 if ($res->numRows() != 1) {
63 return null;
64 }
65 return $res->fetchOneCell();
66 }
67
68 public function prev()
69 {
70 static $val;
71 if (!isset($val)) {
72 $val = $this->selectId("n.id < {$this->_id} ORDER BY n.id DESC");
73 }
74 return $val;
75 }
76
77 public function next()
78 {
79 static $val;
80 if (!isset($val)) {
81 $val = $this->selectId("n.id > {$this->_id} ORDER BY n.id");
82 }
83 return $val;
84 }
85
86 public function last()
87 {
88 static $val;
89 if (!isset($val)) {
90 $res = XDB::query("SELECT MAX(n.id)
91 FROM {$this->_table} AS n
92 WHERE n.bits != 'new' AND n.id > {?}",
93 $this->_id);
94 if ($res->numRows() != 1) {
95 $val = null;
96 } else {
97 $val = $res->fetchOneCell();
98 }
99 }
100 return $val;
101 }
102
16cd99fb 103 public function title($mail = false)
104 {
105 return $mail ? $this->_title_mail : $this->_title;
106 }
107
108 public function head($prenom = null, $nom = null, $sexe = null, $type = 'text')
109 {
110 if (is_null($prenom)) {
111 return $this->_head;
112 } else {
113 $head = $this->_head;
a7de4ef7 114 $head = str_replace('<cher>', $sexe ? 'Chère' : 'Cher', $head);
16cd99fb 115 $head = str_replace('<prenom>', $prenom, $head);
116 $head = str_replace('<nom>', $nom, $head);
8da0d3c1 117 return format_text($head, $type, 2, 64);
16cd99fb 118 }
119 }
120
121 public function css(&$page = null)
122 {
123 if (!is_null($page)) {
124 $page->addCssLink($this->_css);
125 return true;
126 } else {
127 $css = file_get_contents(dirname(__FILE__) . '/../htdocs/css/' . $this->_css);
a14159bf 128 return preg_replace('@/\*.*?\*/@us', '', $css);
16cd99fb 129 }
130 }
131
132 public function toText(&$page, $prenom, $nom, $sexe)
133 {
134 $this->css($page);
135 $page->assign('is_mail', false);
136 $page->assign('html_version', false);
137 $page->assign('prenom', $prenom);
138 $page->assign('nom', $nom);
139 $page->assign('sexe', $sexe);
140 $this->assignData($page);
141 }
142
143 public function toHtml(&$page, $prenom, $nom, $sexe)
144 {
145 $this->css($page);
146 $page->assign('prefix', $this->_prefix . '/' . $this->id());
147 $page->assign('is_mail', false);
148 $page->assign('html_version', true);
149 $page->assign('prenom', $prenom);
150 $page->assign('nom', $nom);
151 $page->assign('sexe', $sexe);
152 $this->assignData($page);
153 }
154
a0f05027 155 public function sendTo($prenom, $nom, $login, $sexe, $html, $hash = 0)
16cd99fb 156 {
157 global $globals;
a0f05027 158 if (strpos($login, '@') === false) {
159 $login = "$login@{$globals->mail->domain}";
160 }
16cd99fb 161
162 $mailer = new PlMailer($this->_tpl);
163 $this->assignData($mailer);
164 $mailer->assign('is_mail', true);
165 $mailer->assign('prenom', $prenom);
166 $mailer->assign('nom', $nom);
167 $mailer->assign('sexe', $sexe);
168 $mailer->assign('prefix', null);
a0f05027 169 $mailer->assign('hash', $hash);
170 $mailer->addTo("\"$prenom $nom\" <$login>");
16cd99fb 171 $mailer->send($html);
172 }
173
a0f05027 174 protected function getAllRecipients()
175 {
b2192733 176 global $globals;
177 return "SELECT u.user_id, CONCAT(a.alias, '@{$globals->mail->domain}'),
a0f05027 178 u.prenom, IF(u.nom_usage='', u.nom, u.nom_usage),
179 FIND_IN_SET('femme', u.flags),
180 q.core_mail_fmt AS pref, 0 AS hash
fc9d9368 181 FROM {$this->_subscriptionTable} AS ni
a0f05027 182 INNER JOIN auth_user_md5 AS u USING(user_id)
183 INNER JOIN auth_user_quick AS q ON(q.user_id = u.user_id)
184 INNER JOIN aliases AS a ON(u.user_id=a.id AND FIND_IN_SET('bestalias',a.flags))
185 LEFT JOIN emails AS e ON(e.uid=u.user_id AND e.flags='active')
186 WHERE ni.last < {?} AND ({$this->subscriptionWhere()}) AND e.email IS NOT NULL
187 GROUP BY u.user_id";
188 }
189
16cd99fb 190 public function sendToAll()
191 {
192 $this->setSent();
a0f05027 193 $query = $this->getAllRecipients() . " LIMIT {?}";
16cd99fb 194 while (true) {
a0f05027 195 $res = XDB::iterRow($query, $this->_id, 60);
16cd99fb 196 if (!$res->total()) {
4e25428d 197 return;
16cd99fb 198 }
199 $sent = array();
a0f05027 200 while (list($uid, $bestalias, $prenom, $nom, $sexe, $fmt, $hash) = $res->next()) {
201 $sent[] = "(user_id='$uid'" . (!$uid ? " AND email='$bestalias')": ')');
202 $this->sendTo($prenom, $nom, $bestalias, $sexe, $fmt=='html', $hash);
16cd99fb 203 }
fc9d9368 204 XDB::execute("UPDATE {$this->_subscriptionTable}
16cd99fb 205 SET last = {?}
206 WHERE " . implode(' OR ', $sent), $this->_id);
b2192733 207
16cd99fb 208 sleep(60);
209 }
210 }
211
212 abstract protected function assignData(&$smarty);
213 abstract protected function setSent();
214
16cd99fb 215 abstract protected function subscriptionWhere();
216}
217
218// }}}
219// {{{ Functions
220
221function justify($text,$n)
222{
223 $arr = explode("\n",wordwrap($text,$n));
224 $arr = array_map('trim',$arr);
225 $res = '';
226 foreach ($arr as $key => $line) {
227 $nxl = isset($arr[$key+1]) ? trim($arr[$key+1]) : '';
228 $nxl_split = preg_split('! +!',$nxl);
229 $nxw_len = count($nxl_split) ? strlen($nxl_split[0]) : 0;
230 $line = trim($line);
231
232 if (strlen($line)+1+$nxw_len < $n) {
233 $res .= "$line\n";
234 continue;
235 }
236
237 if (preg_match('![.:;]$!',$line)) {
238 $res .= "$line\n";
239 continue;
240 }
241
242 $tmp = preg_split('! +!',trim($line));
243 $words = count($tmp);
244 if ($words <= 1) {
245 $res .= "$line\n";
246 continue;
247 }
248
249 $len = array_sum(array_map('strlen',$tmp));
250 $empty = $n - $len;
251 $sw = floatval($empty) / floatval($words-1);
252
253 $cur = 0;
254 $l = '';
255 foreach ($tmp as $word) {
256 $l .= $word;
257 $cur += $sw + strlen($word);
258 $l = str_pad($l,intval($cur+0.5));
259 }
260 $res .= trim($l)."\n";
261 }
262 return trim($res);
263}
264
8da0d3c1 265function format_text($input, $format, $indent = 0, $width = 68)
266{
267 if ($format == 'text') {
268 return enriched_to_text($input, false, true, $indent, $width);
269 }
270 return enriched_to_text($input, true);
271}
272
16cd99fb 273function enriched_to_text($input,$html=false,$just=false,$indent=0,$width=68)
274{
275 $text = trim($input);
276 if ($html) {
277 $text = htmlspecialchars($text);
278 $text = str_replace('[b]','<strong>', $text);
279 $text = str_replace('[/b]','</strong>', $text);
280 $text = str_replace('[i]','<em>', $text);
281 $text = str_replace('[/i]','</em>', $text);
282 $text = str_replace('[u]','<span style="text-decoration: underline">', $text);
283 $text = str_replace('[/u]','</span>', $text);
8da0d3c1 284 $text = preg_replace("!(\\s*\n)*\[title\]!",'<h1>',$text);
285 $text = preg_replace("!\[\/title\](\\s*\n)*!", '</h1>',$text);
286 $text = preg_replace("!(\\s*\n)*\[subtitle\]!",'<h2>',$text);
287 $text = preg_replace("!\[\/subtitle\](\\s*\n)*!",'</h2>',$text);
288
16cd99fb 289 require_once('url_catcher.inc.php');
290 $text = url_catcher($text);
291 return nl2br($text);
292 } else {
293 $text = preg_replace('!\[\/?b\]!','*',$text);
294 $text = preg_replace('!\[\/?u\]!','_',$text);
295 $text = preg_replace('!\[\/?i\]!','/',$text);
8da0d3c1 296 $text = preg_replace('!\[\/?title\]!','***', $text);
297 $text = preg_replace('!\[\/?subtitle\]!','**', $text);
16cd99fb 298 $text = preg_replace('!(((https?|ftp)://|www\.)[^\r\n\t ]*)!','[\1]', $text);
299 $text = preg_replace('!(([a-zA-Z0-9\-_+.]*@[a-zA-Z0-9\-_+.]*)(?:\?[^\r\n\t ]*)?)!','[mailto:\1]', $text);
300 $text = $just ? justify($text,$width-$indent) : wordwrap($text,$width-$indent);
301 if($indent) {
302 $ind = str_pad('',$indent);
303 $text = $ind.str_replace("\n","\n$ind",$text);
304 }
305 return $text;
306 }
307}
308
309// }}}
310
a7de4ef7 311// vim:set et sw=4 sts=4 sws=4 enc=utf-8:
16cd99fb 312?>