2 rcs_id('$Id: MailNotify.php,v 1.1 2006-12-22 17:59:55 rurban Exp $');
5 * Handle the pagelist pref[notifyPages] logic for users
6 * and notify => hash ( page => (userid => userhash) ) for pages.
7 * Generate notification emails.
9 * We add WikiDB handlers and register ourself there:
10 * onDeletePage, onRenamePage
11 * Administrative actions:
12 * [Watch] WatchPage - add a page, or delete watch handlers into the users
13 * pref[notifyPages] slot.
14 * My WatchList - view or edit list/regex of pref[notifyPages].
19 * ? handle emailed confirmation links (EmailSignup, ModeratedPage)
27 function MailNotify($pagename) {
28 $this->pagename = $pagename; /* which page */
29 $this->emails = array(); /* to whch addresses */
30 $this->userids = array(); /* corresponding array of displayed names,
31 dont display the email addersses */
32 /* from: from which the mail appears to be */
33 $this->from = $this->fromId();
38 return $request->_user->getId() . '@' . $request->get('REMOTE_HOST');
41 function userEmail($userid, $doverify = true) {
43 $u = $request->getUser();
44 if ($u->UserName() == $userid) { // lucky: current user
45 $prefs = $u->getPreferences();
46 $email = $prefs->get('email');
47 // do a dynamic emailVerified check update
48 if ($doverify and !$request->_prefs->get('emailVerified'))
50 } else { // not current user
51 if (ENABLE_USER_NEW) {
52 $u = WikiUser($userid);
56 $u = new WikiUser($request, $userid);
57 $prefs = $u->getPreferences();
59 $email = $prefs->get('email');
60 if ($doverify and !$prefs->get('emailVerified')) {
68 * getPageChangeEmails($notify)
69 * @param $notify: hash ( page => (userid => userhash) )
71 * unique array of ($emails, $userids)
73 function getPageChangeEmails($notify) {
75 $emails = array(); $userids = array();
76 foreach ($notify as $page => $users) {
77 if (glob_match($page, $this->pagename)) {
78 foreach ($users as $userid => $user) {
79 if (!$user) { // handle the case for ModeratePage:
80 // no prefs, just userid's.
81 $emails[] = $this->userEmail($userid, false);
84 if (!empty($user['verified']) and !empty($user['email'])) {
85 $emails[] = $user['email'];
87 } elseif (!empty($user['email'])) {
88 // do a dynamic emailVerified check update
89 $email = $this->userEmail($userid, true);
91 $notify[$page][$userid]['verified'] = 1;
92 $request->_dbi->set('notify', $notify);
97 // ignore verification
100 if (!in_array($user['email'],$emails))
101 $emails[] = $user['email'];
108 $this->emails = array_unique($emails);
109 $this->userids = array_unique($userids);
110 return array($this->emails, $this->userids);
113 function sendMail($subject, $content) {
115 $emails = $this->emails;
117 if (mail(array_shift($emails),
118 "[".WIKI_NAME."] ".$subject,
119 $subject."\n".$content,
120 "From: $from\r\nBcc: ".join(',', $emails)
123 trigger_error(sprintf(_("PageChange Notification of %s sent to %s"),
124 $this->pagename, join(',',$this->userids)), E_USER_NOTICE);
127 trigger_error(sprintf(_("PageChange Notification of %s Error: Couldn't send to %s"),
128 $this->pagename, join(',',$this->userids)), E_USER_WARNING);
134 * Send udiff for a changed page to multiple users.
135 * See rename and remove methods also
137 function sendPageChangeNotification(&$wikitext, $version, &$meta) {
141 if (@is_array($request->_deferredPageChangeNotification)) {
142 // collapse multiple changes (loaddir) into one email
143 $request->_deferredPageChangeNotification[] =
144 array($this->pagename, $this->emails, $this->userids);
147 $backend = &$this->_wikidb->_backend;
148 //$backend = &$request->_dbi->_backend;
149 $subject = _("Page change").' '.urlencode($this->pagename);
150 $previous = $backend->get_previous_version($this->pagename, $version);
151 if (!isset($meta['mtime'])) $meta['mtime'] = time();
153 $difflink = WikiURL($this->pagename, array('action'=>'diff'), true);
154 $dbh = &$request->getDbh();
155 $cache = &$dbh->_wikidb->_cache;
156 //$cache = &$request->_dbi->_cache;
157 $content = explode("\n", $wikitext);
158 $prevdata = $cache->get_versiondata($this->pagename, $previous, true);
159 if (empty($prevdata['%content']))
160 $prevdata = $backend->get_versiondata($this->pagename, $previous, true);
161 $other_content = explode("\n", $prevdata['%content']);
163 include_once("lib/difflib.php");
164 $diff2 = new Diff($other_content, $this_content);
165 //$context_lines = max(4, count($other_content) + 1,
166 // count($this_content) + 1);
167 $fmt = new UnifiedDiffFormatter(/*$context_lines*/);
168 $content = $this->pagename . " " . $previous . " " .
169 Iso8601DateTime($prevdata['mtime']) . "\n";
170 $content .= $this->pagename . " " . $version . " " .
171 Iso8601DateTime($meta['mtime']) . "\n";
172 $content .= $fmt->format($diff2);
175 $difflink = WikiURL($this->pagename,array(),true);
176 $content = $this->pagename . " " . $version . " " .
177 Iso8601DateTime($meta['mtime']) . "\n";
178 $content .= _("New page");
180 $editedby = sprintf(_("Edited by: %s"), $this->from);
181 //$editedby = sprintf(_("Edited by: %s"), $meta['author']);
182 $this->sendMail($subject,
183 $editedby."\n".$difflink."\n\n".$content);
187 * support mass rename / remove (not yet tested)
189 function sendPageRenameNotification ($to, &$meta) {
192 if (@is_array($request->_deferredPageRenameNotification)) {
193 $request->_deferredPageRenameNotification[] =
194 array($this->pagename, $to, $meta, $this->emails, $this->userids);
196 $pagename = $this->pagename;
197 //$editedby = sprintf(_("Edited by: %s"), $meta['author']) . ' ' . $meta['author_id'];
198 $editedby = sprintf(_("Edited by: %s"), $this->from);
199 $subject = sprintf(_("Page rename %s to %s"), urlencode($pagename), urlencode($to));
200 $link = WikiURL($to, true);
201 $this->sendMail($subject,
202 $editedby."\n".$link."\n\n"."Renamed $pagename to $to");
209 function onChangePage (&$wikidb, &$wikitext, $version, &$meta) {
211 if (!isa($GLOBALS['request'],'MockRequest')) {
212 $notify = $wikidb->_wikidb->get('notify');
213 /* Generate notification emails? */
214 if (!empty($notify) and is_array($notify)) {
215 if (empty($this->pagename))
216 $this->pagename = $meta['pagename'];
217 //TODO: defer it (quite a massive load if you MassRevert some pages).
218 //TODO: notification class which catches all changes,
219 // and decides at the end of the request what to mail. (type, page, who, what, users, emails)
220 // could be used for PageModeration and RSS2 Cloud xml-rpc also.
221 $this->getPageChangeEmails($notify);
222 if (!empty($this->emails)) {
223 $result = $this->sendPageChangeNotification($wikitext, $version, $meta);
230 function onDeletePage (&$wikidb, $pagename) {
231 /* Generate notification emails? */
232 if (! $wikidb->isWikiPage($pagename) and !isa($GLOBALS['request'],'MockRequest')) {
233 $notify = $wikidb->get('notify');
234 if (!empty($notify) and is_array($notify)) {
235 //TODO: deferr it (quite a massive load if you remove some pages).
236 //TODO: notification class which catches all changes,
237 // and decides at the end of the request what to mail. (type, page, who, what, users, emails)
238 // could be used for PageModeration and RSS2 Cloud xml-rpc also.
239 $page = new WikiDB_Page($wikidb, $pagename);
240 $page->getPageChangeEmails($notify);
241 if (!empty($this->emails)) {
242 $editedby = sprintf(_("Removed by: %s"), $this->from); // Todo: host_id
243 $emails = join(',', $emails);
244 $subject = sprintf(_("Page removed %s"), urlencode($pagename));
245 $result = $this->sendMail($subject,
246 $editedby."\n"."Deleted $pagename"."\n\n".$content);
250 //How to create a RecentChanges entry with explaining summary? Dynamically
252 $page = $this->getPage($pagename);
253 $current = $page->getCurrentRevision();
254 $meta = $current->_data;
255 $version = $current->getVersion();
256 $meta['summary'] = _("removed");
257 $page->save($current->getPackedContent(), $version + 1, $meta);
262 function onRenamePage (&$wikidb, $oldpage, $new_pagename) {
264 if (!isa($GLOBALS['request'], 'MockRequest')) {
265 $notify = $wikidb->get('notify');
266 if (!empty($notify) and is_array($notify)) {
267 $this->getPageChangeEmails($notify);
268 if (!empty($this->emails)) {
269 $newpage = $wikidb->getPage($new_pagename);
270 $current = $newpage->getCurrentRevision();
271 $meta = $current->_data;
272 $this->pagename = $oldpage;
273 $result = $this->sendPageRenameNotification($new_pagename, $meta);
281 // $Log: not supported by cvs2svn $
287 // c-hanging-comment-ender-p: nil
288 // indent-tabs-mode: nil