Commit | Line | Data |
---|---|---|
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 | ||
24 | class MailNotFound extends Exception { | |
25 | } | |
26 | ||
27 | // }}} | |
28 | ||
16cd99fb | 29 | // {{{ class MassMailer |
30 | ||
31 | abstract 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 | ||
d5e60905 | 113 | public function head($user = null, $type = 'text') |
16cd99fb | 114 | { |
d5e60905 | 115 | if (is_null($user)) { |
eaf30d86 | 116 | return $this->_head; |
16cd99fb | 117 | } else { |
118 | $head = $this->_head; | |
d5e60905 FB |
119 | $head = str_replace('<cher>', $user->isFemale() ? 'Chère' : 'Cher', $head); |
120 | $head = str_replace('<prenom>', $user->displayName(), $head); | |
121 | $head = str_replace('<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 | ||
d5e60905 | 137 | public function toText(&$page, $user) |
16cd99fb | 138 | { |
139 | $this->css($page); | |
140 | $page->assign('is_mail', false); | |
3ad44e08 | 141 | $page->assign('mail_part', 'text'); |
d5e60905 | 142 | $page->assign('user', $user); |
16cd99fb | 143 | $this->assignData($page); |
144 | } | |
145 | ||
d5e60905 | 146 | public function toHtml(&$page, $user) |
16cd99fb | 147 | { |
148 | $this->css($page); | |
149 | $page->assign('prefix', $this->_prefix . '/' . $this->id()); | |
150 | $page->assign('is_mail', false); | |
3ad44e08 | 151 | $page->assign('mail_part', 'html'); |
d5e60905 | 152 | $page->assign('user', $user); |
16cd99fb | 153 | $this->assignData($page); |
154 | } | |
155 | ||
39337e2d FB |
156 | private function createHash($line, $key = null) |
157 | { | |
158 | $hash = implode(time(), $line) . rand(); | |
159 | $hash = md5($hash); | |
160 | return $hash; | |
161 | } | |
162 | ||
d5e60905 | 163 | public function sendTo($user, $hash = null) |
16cd99fb | 164 | { |
d5e60905 FB |
165 | if (is_null($hash)) { |
166 | $hash = XDB::fetchOneCell("SELECT hash | |
167 | FROM {$this->_subscriptionTable} | |
1bf36cd1 | 168 | WHERE uid = {?}", $user->id()); |
9833e186 | 169 | } |
d5e60905 FB |
170 | if (is_null($hash)) { |
171 | $hash = $this->createHash(array($user->displayName(), $user->fullName(), | |
172 | $user->isFemale(), $user->isEmailFormatHtml(), | |
173 | rand(), "X.org rulez")); | |
174 | XDB::execute("UPDATE {$this->_subscriptionTable} as ni | |
175 | SET ni.hash = {?} | |
d75eb892 | 176 | WHERE ni.uid = {?}", |
d5e60905 | 177 | $hash, $user->id()); |
39337e2d | 178 | } |
16cd99fb | 179 | |
180 | $mailer = new PlMailer($this->_tpl); | |
181 | $this->assignData($mailer); | |
182 | $mailer->assign('is_mail', true); | |
d5e60905 | 183 | $mailer->assign('user', $user); |
16cd99fb | 184 | $mailer->assign('prefix', null); |
a0f05027 | 185 | $mailer->assign('hash', $hash); |
d5e60905 FB |
186 | $mailer->addTo('"' . $user->fullName() . '" <' . $user->bestEmail() . '>'); |
187 | $mailer->send($user->isEmailFormatHtml()); | |
16cd99fb | 188 | } |
189 | ||
a0f05027 | 190 | protected function getAllRecipients() |
191 | { | |
b2192733 | 192 | global $globals; |
2d88346f | 193 | return "SELECT a.uid |
fc9d9368 | 194 | FROM {$this->_subscriptionTable} AS ni |
1bf36cd1 | 195 | INNER JOIN accounts AS a ON (ni.uid = a.uid) |
d5e60905 FB |
196 | LEFT JOIN email_options AS eo ON (eo.uid = a.uid) |
197 | LEFT JOIN emails AS e ON (e.uid = a.uid AND e.flags='active') | |
c3b45f48 | 198 | WHERE ni.last < {?} AND ({$this->subscriptionWhere()}) AND |
d5e60905 FB |
199 | (e.email IS NOT NULL OR FIND_IN_SET('googleapps', eo.storage)) |
200 | GROUP BY a.uid"; | |
a0f05027 | 201 | } |
202 | ||
16cd99fb | 203 | public function sendToAll() |
204 | { | |
205 | $this->setSent(); | |
1f46b961 | 206 | $query = XDB::format($this->getAllRecipients(), $this->_id) . ' LIMIT 60'; |
16925f01 SJ |
207 | $emailsCount = 0; |
208 | ||
16cd99fb | 209 | while (true) { |
2d88346f FB |
210 | $users = User::getBulkUsersWithUIDs(XDB::fetchColumn($query)); |
211 | if (count($users) == 0) { | |
16925f01 | 212 | return $emailsCount; |
16cd99fb | 213 | } |
2d88346f | 214 | foreach ($users as $user) { |
1bf36cd1 | 215 | $sent[] = XDB::format('uid = {?}', $user->id()); |
d5e60905 | 216 | $this->sendTo($user, $hash); |
16925f01 | 217 | ++$emailsCount; |
16cd99fb | 218 | } |
fc9d9368 | 219 | XDB::execute("UPDATE {$this->_subscriptionTable} |
16cd99fb | 220 | SET last = {?} |
221 | WHERE " . implode(' OR ', $sent), $this->_id); | |
eaf30d86 | 222 | |
16cd99fb | 223 | sleep(60); |
224 | } | |
84480022 | 225 | return $emailsCount; |
16cd99fb | 226 | } |
227 | ||
228 | abstract protected function assignData(&$smarty); | |
229 | abstract protected function setSent(); | |
230 | ||
16cd99fb | 231 | abstract protected function subscriptionWhere(); |
232 | } | |
233 | ||
234 | // }}} | |
235 | // {{{ Functions | |
236 | ||
8da0d3c1 | 237 | function format_text($input, $format, $indent = 0, $width = 68) |
238 | { | |
239 | if ($format == 'text') { | |
02fdd1c8 | 240 | return MiniWiki::WikiToText($input, true, $indent, $width, "title"); |
8da0d3c1 | 241 | } |
02fdd1c8 | 242 | return MiniWiki::WikiToHTML($input, "title"); |
8da0d3c1 | 243 | } |
244 | ||
02fdd1c8 | 245 | // function enriched_to_text($input,$html=false,$just=false,$indent=0,$width=68) |
16cd99fb | 246 | |
247 | // }}} | |
248 | ||
a7de4ef7 | 249 | // vim:set et sw=4 sts=4 sws=4 enc=utf-8: |
16cd99fb | 250 | ?> |