<?php
/***************************************************************************
- * Copyright (C) 2003-2007 Polytechnique.org *
+ * Copyright (C) 2003-2009 Polytechnique.org *
* http://opensource.polytechnique.org/ *
* *
* This program is free software; you can redistribute it and/or modify *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
***************************************************************************/
-require_once("xorg.misc.inc.php");
+// {{{ class MailNotFound
+
+class MailNotFound extends Exception {
+}
+
+// }}}
// {{{ class MassMailer
public $_head;
- function __construct($tpl, $css, $prefix)
+ protected $_table;
+ protected $_subscriptionTable;
+
+ function __construct($tpl, $css, $prefix, $tbl, $stbl)
{
$this->_tpl = $tpl;
$this->_css = $css;
$this->_prefix = $prefix;
+ $this->_table = $tbl;
+ $this->_subscriptionTable = $stbl;
}
public function id()
return is_null($this->_shortname) ? $this->_id : $this->_shortname;
}
+ private function selectId($where)
+ {
+ $res = XDB::query("SELECT IF (n.short_name IS NULL, n.id, n.short_name)
+ FROM {$this->_table} AS n
+ WHERE n.bits != 'new' AND {$where}
+ LIMIT 1");
+ if ($res->numRows() != 1) {
+ return null;
+ }
+ return $res->fetchOneCell();
+ }
+
+ public function prev()
+ {
+ static $val;
+ if (!isset($val)) {
+ $val = $this->selectId("n.id < {$this->_id} ORDER BY n.id DESC");
+ }
+ return $val;
+ }
+
+ public function next()
+ {
+ static $val;
+ if (!isset($val)) {
+ $val = $this->selectId("n.id > {$this->_id} ORDER BY n.id");
+ }
+ return $val;
+ }
+
+ public function last()
+ {
+ static $val;
+ if (!isset($val)) {
+ $res = XDB::query("SELECT MAX(n.id)
+ FROM {$this->_table} AS n
+ WHERE n.bits != 'new' AND n.id > {?}",
+ $this->_id);
+ if ($res->numRows() != 1) {
+ $val = null;
+ } else {
+ $val = $res->fetchOneCell();
+ }
+ }
+ return $val;
+ }
+
public function title($mail = false)
{
return $mail ? $this->_title_mail : $this->_title;
public function head($prenom = null, $nom = null, $sexe = null, $type = 'text')
{
if (is_null($prenom)) {
- return $this->_head;
+ return $this->_head;
} else {
$head = $this->_head;
$head = str_replace('<cher>', $sexe ? 'Chère' : 'Cher', $head);
{
$this->css($page);
$page->assign('is_mail', false);
- $page->assign('html_version', false);
+ $page->assign('mail_part', 'text');
$page->assign('prenom', $prenom);
$page->assign('nom', $nom);
$page->assign('sexe', $sexe);
$this->css($page);
$page->assign('prefix', $this->_prefix . '/' . $this->id());
$page->assign('is_mail', false);
- $page->assign('html_version', true);
+ $page->assign('mail_part', 'html');
$page->assign('prenom', $prenom);
$page->assign('nom', $nom);
$page->assign('sexe', $sexe);
$this->assignData($page);
}
- public function sendTo($prenom, $nom, $login, $sexe, $html, $hash = 0)
+ private function createHash($line, $key = null)
{
- global $globals;
- if (strpos($login, '@') === false) {
- $login = "$login@{$globals->mail->domain}";
+ $hash = implode(time(), $line) . rand();
+ $hash = md5($hash);
+ return $hash;
+ }
+
+ public function sendTo($hruid, $email, $prenom, $nom, $sexe, $html, $hash = 0)
+ {
+ // If $email is not a real email address, tries to compute it up from
+ // the hruid. Otherwise, we suppose that caller will have used a valid
+ // and canonical email address.
+ if (strpos($email, '@') === false) {
+ if (!($user = User::getSilent($email))) {
+ Platal::page()->trigError("'$email' is neither a valid email address nor a valid login; did not send the email.");
+ }
+ $email = $user->bestEmail();
+ }
+
+ if ($hruid && (is_null($hash) || $hash == 0)) {
+ $hash = $this->createHash(array($email, $prenom, $nom, $sexe, $html, rand(), "X.org rulez"));
+ XDB::query("UPDATE {$this->_subscriptionTable} as ni
+ INNER JOIN auth_user_md5 AS u USING (user_id)
+ SET ni.hash = {?}
+ WHERE ni.user_id != 0 AND u.hruid = {?}",
+ $hash, $hruid);
}
$mailer = new PlMailer($this->_tpl);
$mailer->assign('sexe', $sexe);
$mailer->assign('prefix', null);
$mailer->assign('hash', $hash);
- $mailer->addTo("\"$prenom $nom\" <$login>");
+ $mailer->assign('email', $email);
+ $mailer->assign('alias', $hruid);
+ $mailer->addTo("\"$prenom $nom\" <$email>");
$mailer->send($html);
}
protected function getAllRecipients()
{
global $globals;
- return "SELECT u.user_id, CONCAT(a.alias, '@{$globals->mail->domain}'),
+ return "SELECT u.user_id, u.hruid, CONCAT(a.alias, '@{$globals->mail->domain}'),
u.prenom, IF(u.nom_usage='', u.nom, u.nom_usage),
FIND_IN_SET('femme', u.flags),
- q.core_mail_fmt AS pref, 0 AS hash
- FROM {$this->subscriptionTable()} AS ni
+ q.core_mail_fmt AS pref, ni.hash AS hash
+ FROM {$this->_subscriptionTable} AS ni
INNER JOIN auth_user_md5 AS u USING(user_id)
INNER JOIN auth_user_quick AS q ON(q.user_id = u.user_id)
INNER JOIN aliases AS a ON(u.user_id=a.id AND FIND_IN_SET('bestalias',a.flags))
LEFT JOIN emails AS e ON(e.uid=u.user_id AND e.flags='active')
- WHERE ni.last < {?} AND ({$this->subscriptionWhere()}) AND e.email IS NOT NULL
+ WHERE ni.last < {?} AND ({$this->subscriptionWhere()}) AND
+ (e.email IS NOT NULL OR FIND_IN_SET('googleapps', u.mail_storage))
GROUP BY u.user_id";
}
return;
}
$sent = array();
- while (list($uid, $bestalias, $prenom, $nom, $sexe, $fmt, $hash) = $res->next()) {
- $sent[] = "(user_id='$uid'" . (!$uid ? " AND email='$bestalias')": ')');
- $this->sendTo($prenom, $nom, $bestalias, $sexe, $fmt=='html', $hash);
+ while (list($uid, $hruid, $email, $prenom, $nom, $sexe, $fmt, $hash) = $res->next()) {
+ $sent[] = "(user_id='$uid'" . (!$uid ? " AND email='$email')": ')');
+ $this->sendTo($hruid, $email, $prenom, $nom, $sexe, $fmt=='html', $hash);
}
- XDB::execute("UPDATE {$this->subscriptionTable()}
+ XDB::execute("UPDATE {$this->_subscriptionTable}
SET last = {?}
WHERE " . implode(' OR ', $sent), $this->_id);
-
+
sleep(60);
}
}
abstract protected function assignData(&$smarty);
abstract protected function setSent();
- abstract protected function subscriptionTable();
abstract protected function subscriptionWhere();
}
// }}}
// {{{ Functions
-function justify($text,$n)
-{
- $arr = explode("\n",wordwrap($text,$n));
- $arr = array_map('trim',$arr);
- $res = '';
- foreach ($arr as $key => $line) {
- $nxl = isset($arr[$key+1]) ? trim($arr[$key+1]) : '';
- $nxl_split = preg_split('! +!',$nxl);
- $nxw_len = count($nxl_split) ? strlen($nxl_split[0]) : 0;
- $line = trim($line);
-
- if (strlen($line)+1+$nxw_len < $n) {
- $res .= "$line\n";
- continue;
- }
-
- if (preg_match('![.:;]$!',$line)) {
- $res .= "$line\n";
- continue;
- }
-
- $tmp = preg_split('! +!',trim($line));
- $words = count($tmp);
- if ($words <= 1) {
- $res .= "$line\n";
- continue;
- }
-
- $len = array_sum(array_map('strlen',$tmp));
- $empty = $n - $len;
- $sw = floatval($empty) / floatval($words-1);
-
- $cur = 0;
- $l = '';
- foreach ($tmp as $word) {
- $l .= $word;
- $cur += $sw + strlen($word);
- $l = str_pad($l,intval($cur+0.5));
- }
- $res .= trim($l)."\n";
- }
- return trim($res);
-}
-
function format_text($input, $format, $indent = 0, $width = 68)
{
if ($format == 'text') {
- return enriched_to_text($input, false, true, $indent, $width);
+ return MiniWiki::WikiToText($input, true, $indent, $width, "title");
}
- return enriched_to_text($input, true);
+ return MiniWiki::WikiToHTML($input, "title");
}
-function enriched_to_text($input,$html=false,$just=false,$indent=0,$width=68)
-{
- $text = trim($input);
- if ($html) {
- $text = htmlspecialchars($text);
- $text = str_replace('[b]','<strong>', $text);
- $text = str_replace('[/b]','</strong>', $text);
- $text = str_replace('[i]','<em>', $text);
- $text = str_replace('[/i]','</em>', $text);
- $text = str_replace('[u]','<span style="text-decoration: underline">', $text);
- $text = str_replace('[/u]','</span>', $text);
- $text = preg_replace("!(\\s*\n)*\[title\]!",'<h1>',$text);
- $text = preg_replace("!\[\/title\](\\s*\n)*!", '</h1>',$text);
- $text = preg_replace("!(\\s*\n)*\[subtitle\]!",'<h2>',$text);
- $text = preg_replace("!\[\/subtitle\](\\s*\n)*!",'</h2>',$text);
-
- require_once('url_catcher.inc.php');
- $text = url_catcher($text);
- return nl2br($text);
- } else {
- $text = preg_replace('!\[\/?b\]!','*',$text);
- $text = preg_replace('!\[\/?u\]!','_',$text);
- $text = preg_replace('!\[\/?i\]!','/',$text);
- $text = preg_replace('!\[\/?title\]!','***', $text);
- $text = preg_replace('!\[\/?subtitle\]!','**', $text);
- $text = preg_replace('!(((https?|ftp)://|www\.)[^\r\n\t ]*)!','[\1]', $text);
- $text = preg_replace('!(([a-zA-Z0-9\-_+.]*@[a-zA-Z0-9\-_+.]*)(?:\?[^\r\n\t ]*)?)!','[mailto:\1]', $text);
- $text = $just ? justify($text,$width-$indent) : wordwrap($text,$width-$indent);
- if($indent) {
- $ind = str_pad('',$indent);
- $text = $ind.str_replace("\n","\n$ind",$text);
- }
- return $text;
- }
-}
+// function enriched_to_text($input,$html=false,$just=false,$indent=0,$width=68)
// }}}