#525: Add a user-friendly Id for the NLs.
[platal.git] / include / newsletter.inc.php
CommitLineData
0337d704 1<?php
2/***************************************************************************
50a40a33 3 * Copyright (C) 2003-2006 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
22// {{{ requires + defines
23
24require_once("xorg.misc.inc.php");
0337d704 25
26if (isset($page)) {
c99ef281 27 $page->addCssLink('nl.css');
0337d704 28}
29
30define('FEMME', 1);
31define('HOMME', 0);
32
33// }}}
34// {{{ class NewsLetter
35
36class NewsLetter
37{
38 // {{{ properties
39
40 var $_id;
ed76a506 41 var $_shortname;
0337d704 42 var $_date;
43 var $_title;
44 var $_head;
45 var $_cats = Array();
46 var $_arts = Array();
47
48 // }}}
49 // {{{ constructor
50
51 function NewsLetter($id=null)
52 {
ed76a506 53 if (isset($id)) {
54 if ($id == 'last') {
55 $res = XDB::query("SELECT MAX(id) FROM newsletter WHERE bits!='new'");
0337d704 56 $id = $res->fetchOneCell();
ed76a506 57 }
58 $res = XDB::query("SELECT * FROM newsletter WHERE id={?} OR short_name={?} LIMIT 1", $id, $id);
59 } else {
60 $res = XDB::query("SELECT * FROM newsletter WHERE bits='new'");
61 if (!$res->numRows()) {
62 insert_new_nl();
63 }
64 $res = XDB::query("SELECT * FROM newsletter WHERE bits='new'");
ad6ca77d 65 }
ed76a506 66 $nl = $res->fetchOneAssoc();
0337d704 67
ed76a506 68 $this->_id = $nl['id'];
69 $this->_shortname = $nl['short_name'];
70 $this->_date = $nl['date'];
71 $this->_title = $nl['titre'];
72 $this->_head = $nl['head'];
0337d704 73
ed76a506 74 $res = XDB::iterRow("SELECT cid,titre FROM newsletter_cat ORDER BY pos");
75 while (list($cid, $title) = $res->next()) {
76 $this->_cats[$cid] = $title;
77 }
ad6ca77d 78
ed76a506 79 $res = XDB::iterRow(
0337d704 80 "SELECT a.title,a.body,a.append,a.aid,a.cid,a.pos
81 FROM newsletter_art AS a
82 INNER JOIN newsletter AS n USING(id)
83 LEFT JOIN newsletter_cat AS c ON(a.cid=c.cid)
84 WHERE a.id={?}
85 ORDER BY c.pos,a.pos", $this->_id);
ed76a506 86 while (list($title, $body, $append, $aid, $cid, $pos) = $res->next()) {
87 $this->_arts[$cid]["a$aid"] = new NLArticle($title, $body, $append, $aid, $cid, $pos);
88 }
0337d704 89 }
90
91 // }}}
92 // {{{ function setSent()
93
94 function setSent()
95 {
ad6ca77d 96 XDB::execute("UPDATE newsletter SET bits='sent' WHERE id={?}", $this->_id);
0337d704 97 }
98
99 // }}}
100 // {{{ function save()
101
102 function save()
103 {
ed76a506 104 XDB::execute('UPDATE newsletter SET date={?},titre={?},head={?},short_name={?} WHERE id={?}',
105 $this->_date, $this->_title, $this->_head, $this->_shortname,$this->_id);
106 }
107
108 // }}}
109 // {{{ function id()
110
111 function id()
112 {
113 return is_null($this->_shortname) ? $this->_id : $this->_shortname;
0337d704 114 }
115
116 // }}}
117 // {{{ function title()
118
119 function title()
120 { return $this->_title; }
121
122 // }}}
123 // {{{ function head()
124
125 function head()
126 { return $this->_head; }
127
128 // }}}
129 // {{{ function getArt()
130
131 function getArt($aid)
132 {
ad6ca77d 133 foreach ($this->_arts as $key=>$artlist) {
134 if (isset($artlist["a$aid"])) {
0337d704 135 return $artlist["a$aid"];
136 }
ad6ca77d 137 }
138 return null;
0337d704 139 }
140
141 // }}}
142 // {{{ function saveArticle()
143
144 function saveArticle(&$a)
145 {
ad6ca77d 146 if ($a->_aid>=0) {
147 XDB::execute('REPLACE INTO newsletter_art (id,aid,cid,pos,title,body,append)
0337d704 148 VALUES ({?},{?},{?},{?},{?},{?},{?})',
149 $this->_id, $a->_aid, $a->_cid, $a->_pos,
150 $a->_title, $a->_body, $a->_append);
ad6ca77d 151 $this->_arts['a'.$a->_aid] = $a;
152 } else {
153 XDB::execute(
154 'INSERT INTO newsletter_art
155 SELECT {?},MAX(aid)+1,{?},'.($a->_pos ? intval($a->_pos) : 'MAX(pos)+1').',{?},{?},{?}
156 FROM newsletter_art AS a
157 WHERE a.id={?}',
0337d704 158 $this->_id, $a->_cid, $a->_title, $a->_body, $a->_append, $this->_id);
ad6ca77d 159 $this->_arts['a'.$a->_aid] = $a;
160 }
0337d704 161 }
162
163 // }}}
164 // {{{ function delArticle()
165
166 function delArticle($aid)
167 {
ad6ca77d 168 XDB::execute('DELETE FROM newsletter_art WHERE id={?} AND aid={?}', $this->_id, $aid);
169 foreach ($this->_arts as $key=>$art) {
170 unset($this->_arts[$key]["a$aid"]);
171 }
0337d704 172 }
173
174 // }}}
175 // {{{ function footer
176
177 function footer($html)
178 {
179 global $globals;
736dcfda 180 $url = 'https://www.polytechnique.org';
0337d704 181
ad6ca77d 182 if ($html) {
183 return '<div class="foot">Cette lettre est envoyée à tous les Polytechniciens sur Internet par l\'intermédiaire de Polytechnique.org.</div>'
184 . '<div class="foot">'
185 . "[<a href=\"$url/nl\">archives</a>&nbsp;|&nbsp;"
186 . "<a href=\"$url/nl/submit\">écrire dans la NL</a>&nbsp;|&nbsp;"
187 . "<a href=\"$url/nl/out\">ne plus recevoir</a>]"
188 . '</div>';
189 } else {
190 return "\n\n--------------------------------------------------------------------\n"
191 . "Cette lettre est envoyée à tous les Polytechniciens sur Internet par\n"
192 . "l'intermédiaire de Polytechnique.org.\n"
193 . "\n"
194 . "archives : [$url/nl]\n"
195 . "écrire : [$url/nl/submit]\n"
196 . "ne plus recevoir: [$url/nl/out]\n";
197 }
0337d704 198 }
199
200 // }}}
201 // {{{ function toText()
202
203 function toText($prenom,$nom,$sexe)
204 {
ad6ca77d 205 $res = "====================================================================\n";
206 $res .= ' '.$this->title()."\n";
207 $res .= "====================================================================\n\n";
0337d704 208
ad6ca77d 209 $head = $this->head();
210 $head = str_replace('<cher>', $sexe ? 'Chère' : 'Cher', $head);
211 $head = str_replace('<prenom>', $prenom, $head);
212 $head = str_replace('<nom>', $nom, $head);
213 $head = enriched_to_text($head,false,true,2,64);
0337d704 214
ad6ca77d 215 if ($head) {
0337d704 216 $res .= "\n$head\n\n\n";
217 }
218
ad6ca77d 219 $i = 1;
220 foreach ($this->_arts as $cid=>$arts) {
221 $res .= "\n$i *{$this->_cats[$cid]}*\n";
222 foreach ($arts as $art) {
223 $res .= '- '.$art->title()."\n";
224 }
225 $i ++;
226 }
227 $res .= "\n\n";
228
229 foreach ($this->_arts as $cid=>$arts) {
230 $res .= "--------------------------------------------------------------------\n";
231 $res .= "*{$this->_cats[$cid]}*\n";
232 $res .= "--------------------------------------------------------------------\n\n";
233 foreach ($arts as $art) {
234 $res .= $art->toText();
235 $res .= "\n\n";
236 }
237 }
238
239 $res .= $this->footer(false);
240
241 return $res;
0337d704 242 }
243
244 // }}}
245 // {{{ function toHtml()
246
6795ed86 247 function toHtml($prenom, $nom, $sexe, $body=false, $urlprefix = false)
0337d704 248 {
ed76a506 249 $u = $urlprefix ? 'nl/show/'.$this->id() : '';
ad6ca77d 250 $res = '<div class="title">'.$this->title().'</div>';
251
252 $head = $this->head();
253 $head = str_replace('<cher>', $sexe ? 'Chère' : 'Cher', $head);
254 $head = str_replace('<prenom>', $prenom, $head);
255 $head = str_replace('<nom>', $nom, $head);
256 $head = enriched_to_text($head, true);
257
258 if($head) {
0337d704 259 $res .= "<div class='intro'>$head</div>";
260 }
261
ad6ca77d 262 $i = 1;
263 $res .= "<a id='top_lnk'></a>";
264 foreach ($this->_arts as $cid=>$arts) {
265 $res .= "<div class='lnk'><a href='$u#cat$cid'><strong>$i. {$this->_cats[$cid]}</strong></a>";
266 foreach ($arts as $art) {
267 $res .= "<a href='$u#art{$art->_aid}'>&nbsp;&nbsp;- ".htmlentities($art->title())."</a>";
268 }
269 $res .= '</div>';
270 $i ++;
271 }
272
273 foreach ($this->_arts as $cid=>$arts) {
274 $res .= "<h1 class='xorg_nl'><a id='cat$cid'></a><span>".$this->_cats[$cid].'</span></h1>';
275 foreach($arts as $art) {
276 $res .= $art->toHtml();
277 $res .= "<p><a href='$u#top_lnk'>Revenir au sommaire</a></p>";
278 }
279 }
280
281 $res .= $this->footer(true);
282
283 if ($body) {
284 $res = <<<EOF
0337d704 285<html>
286 <head>
287 <style type="text/css">
288 <!--
289 div.nl { margin: auto; font-family: "Georgia","times new roman",serif; width: 60ex; text-align: justify; font-size: 10pt; }
290 div.title { margin: 2ex 0ex 2ex 0ex; padding: 1ex; width: 100%; font-size: 140%; text-align: center;
ad6ca77d 291 font-weight: bold; border-bottom: 3px red solid; border-top: 3px red solid; }
0337d704 292
293 a[href] { text-decoration: none; }
294 a[href]:hover { text-decoration: underline; }
295
296 div.lnk { margin: 2ex 0ex 2ex 0ex; padding: 0ex 2ex 0ex 2ex; }
297 div.lnk a { display: block; }
298
04d33ba9 299 h1.xorg_nl { margin: 6ex 0ex 4ex 0ex; padding: 2px 4ex 2px 0ex; width: 60ex; font-size: 100%;
ad6ca77d 300 border-bottom: 3px red solid; border-top: 3px red solid; }
04d33ba9 301 h2.xorg_nl { width: 100%; margin: 0ex 1ex 0ex 1ex; padding: 2px 0px 2px 0px; font-weight: bold; font-style: italic; font-size: 95%; }
302 h1.xorg_nl span { font-size: 140%; padding: 2px 1ex 2px 1ex; border-bottom: 3px red solid; }
303 h2.xorg_nl span { padding: 2px 4px 2px 4px; border-bottom: 2px yellow solid; }
0337d704 304
305 div.art { padding: 2ex; margin: 0ex 1ex 2ex 1ex; width: 58ex; border-top: 2px yellow solid; }
306 div.app { padding: 2ex 3ex 0ex 3ex; width: 100%; margin: 0ex; text-align: left; font-size: 95%; }
307 div.intro { padding: 2ex; }
308 div.foot { border-top: 1px #808080 dashed; font-size: 95%; padding: 1ex; color: #808080; background: inherit;
ad6ca77d 309 text-align: center; width: 100% }
0337d704 310 -->
311 </style>
312 </head>
313 <body>
314 <div class='nl'>
315 $res
316 </div>
317 </body>
318</html>
319EOF;
ad6ca77d 320 }
321 return $res;
0337d704 322 }
323
324 // }}}
325 // {{{ function sendTo()
326
327 function sendTo($prenom, $nom, $login, $sex, $html)
328 {
329 global $globals;
ad6ca77d 330 require_once('diogenes/diogenes.hermes.inc.php');
0337d704 331
ad6ca77d 332 $mailer = new HermesMailer();
333 $mailer->setFrom($globals->newsletter->from);
334 $mailer->setSubject($this->title());
335 $mailer->addTo("\"$prenom $nom\" <$login@{$globals->mail->domain}>");
0337d704 336 if (!empty($globals->newsletter->replyto)) {
337 $mailer->addHeader('Reply-To',$globals->newsletter->replyto);
338 }
339 if (!empty($globals->newsletter->retpath)) {
340 $mailer->addHeader('Return-Path',$globals->newsletter->retpath);
341 }
ad6ca77d 342 $mailer->setTxtBody($this->toText($prenom,$nom,$sex));
343 if ($html) {
344 $mailer->setHTMLBody($this->toHtml($prenom,$nom,$sex,true));
345 }
346 $mailer->send();
0337d704 347 }
348
349 // }}}
350}
351
352// }}}
353// {{{ class NLArticle
354
355class NLArticle
356{
357 // {{{ properties
358
359 var $_aid;
360 var $_cid;
361 var $_pos;
362 var $_title;
363 var $_body;
364 var $_append;
365
366 // }}}
367 // {{{ constructor
368
369 function NLArticle($title='', $body='', $append='', $aid=-1, $cid=0, $pos=0)
370 {
ad6ca77d 371 $this->_body = $body;
372 $this->_title = $title;
373 $this->_append = $append;
374 $this->_aid = $aid;
375 $this->_cid = $cid;
376 $this->_pos = $pos;
0337d704 377 }
378
379 // }}}
380 // {{{ function title()
381
382 function title()
383 { return trim($this->_title); }
384
385 // }}}
386 // {{{ function body()
387
388 function body()
389 { return trim($this->_body); }
390
391 // }}}
392 // {{{ function append()
393
394 function append()
395 { return trim($this->_append); }
396
397 // }}}
398 // {{{ function toText()
399
400 function toText()
401 {
ad6ca77d 402 $title = '*'.$this->title().'*';
403 $body = enriched_to_text($this->_body,false,true);
404 $app = enriched_to_text($this->_append,false,false,4);
405 return trim("$title\n\n$body\n\n$app")."\n";
0337d704 406 }
407
408 // }}}
409 // {{{ function toHtml()
410
411 function toHtml()
412 {
ad6ca77d 413 $title = "<h2 class='xorg_nl'><a id='art{$this->_aid}'></a><span>".htmlentities($this->title()).'</span></h2>';
414 $body = enriched_to_text($this->_body,true);
415 $app = enriched_to_text($this->_append,true);
416
417 $art = "$title\n";
418 $art .= "<div class='art'>\n$body\n";
419 if ($app) {
0337d704 420 $art .= "<div class='app'>$app</div>";
421 }
ad6ca77d 422 $art .= "</div>\n";
423
424 return $art;
0337d704 425 }
426
427 // }}}
428 // {{{ function check()
429
430 function check()
431 {
ad6ca77d 432 $text = enriched_to_text($this->_body);
433 $arr = explode("\n",wordwrap($text,68));
434 $c = 0;
435 foreach ($arr as $line) {
0337d704 436 if (trim($line)) {
437 $c++;
438 }
439 }
ad6ca77d 440 return $c<9;
0337d704 441 }
442
443 // }}}
444}
445
446// }}}
447// {{{ Functions
448
449function insert_new_nl()
450{
08cce2ff 451 XDB::execute("INSERT INTO newsletter SET bits='new',date=NOW(),titre='to be continued'");
0337d704 452}
453
454function get_nl_slist()
455{
ed76a506 456 $res = XDB::query("SELECT IF(short_name IS NULL, id,short_name) as id,date,titre FROM newsletter ORDER BY date DESC");
0337d704 457 return $res->fetchAllAssoc();
458}
459
460function get_nl_list()
461{
ed76a506 462 $res = XDB::query("SELECT IF(short_name IS NULL, id,short_name) as id,date,titre FROM newsletter WHERE bits!='new' ORDER BY date DESC");
0337d704 463 return $res->fetchAllAssoc();
464}
465
466function get_nl_state()
467{
cab08090 468 $res = XDB::query('SELECT 1 FROM newsletter_ins WHERE user_id={?}', S::v('uid'));
0337d704 469 return $res->fetchOneCell();
470}
471
472function unsubscribe_nl()
473{
cab08090 474 XDB::execute('DELETE FROM newsletter_ins WHERE user_id={?}', S::v('uid'));
0337d704 475}
476
477function subscribe_nl($uid=-1)
478{
cab08090 479 $user = ($uid == -1) ? S::v('uid') : $uid;
08cce2ff 480 XDB::execute('REPLACE INTO newsletter_ins (user_id,last)
a3a049fc 481 VALUES ({?}, 0)', $user);
0337d704 482}
483
484function justify($text,$n)
485{
575dd9be 486 $arr = explode("\n",wordwrap($text,$n));
0337d704 487 $arr = array_map('trim',$arr);
488 $res = '';
489 foreach ($arr as $key => $line) {
ad6ca77d 490 $nxl = isset($arr[$key+1]) ? trim($arr[$key+1]) : '';
491 $nxl_split = preg_split('! +!',$nxl);
492 $nxw_len = count($nxl_split) ? strlen($nxl_split[0]) : 0;
493 $line = trim($line);
494
495 if (strlen($line)+1+$nxw_len < $n) {
496 $res .= "$line\n";
497 continue;
498 }
499
500 if (preg_match('![.:;]$!',$line)) {
501 $res .= "$line\n";
502 continue;
503 }
504
505 $tmp = preg_split('! +!',trim($line));
506 $words = count($tmp);
507 if ($words <= 1) {
508 $res .= "$line\n";
509 continue;
510 }
511
512 $len = array_sum(array_map('strlen',$tmp));
513 $empty = $n - $len;
514 $sw = floatval($empty) / floatval($words-1);
515
516 $cur = 0;
517 $l = '';
518 foreach ($tmp as $word) {
519 $l .= $word;
520 $cur += $sw + strlen($word);
521 $l = str_pad($l,intval($cur+0.5));
522 }
523 $res .= trim($l)."\n";
0337d704 524 }
525 return trim($res);
526}
527
528function enriched_to_text($input,$html=false,$just=false,$indent=0,$width=68)
529{
530 $text = trim($input);
531 if ($html) {
ad6ca77d 532 $text = htmlspecialchars($text);
533 $text = str_replace('[b]','<strong>', $text);
534 $text = str_replace('[/b]','</strong>', $text);
535 $text = str_replace('[i]','<em>', $text);
536 $text = str_replace('[/i]','</em>', $text);
537 $text = str_replace('[u]','<span style="text-decoration: underline">', $text);
538 $text = str_replace('[/u]','</span>', $text);
539 require_once('url_catcher.inc.php');
540 $text = url_catcher($text);
541 return nl2br($text);
0337d704 542 } else {
ad6ca77d 543 $text = preg_replace('!\[\/?b\]!','*',$text);
544 $text = preg_replace('!\[\/?u\]!','_',$text);
545 $text = preg_replace('!\[\/?i\]!','/',$text);
546 $text = preg_replace('!(((https?|ftp)://|www\.)[^\r\n\t ]*)!','[\1]', $text);
547 $text = preg_replace('!(([a-zA-Z0-9\-_+.]*@[a-zA-Z0-9\-_+.]*)(?:\?[^\r\n\t ]*)?)!','[mailto:\1]', $text);
548 $text = $just ? justify($text,$width-$indent) : wordwrap($text,$width-$indent);
549 if($indent) {
550 $ind = str_pad('',$indent);
551 $text = $ind.str_replace("\n","\n$ind",$text);
552 }
553 return $text;
0337d704 554 }
555}
556
557// }}}
558
559// vim:set et sw=4 sts=4 sws=4:
560?>