b3f118159d43560bc4bc3d5c34b77b12f6581f98
[atutor.git] / mods / wiki / plugins / notify.php
1 <?php
2 #
3 #  The otherwise invisible markup [notify:you@there.net] will trigger a
4 #  mail, whenever a page is changed. The TLD decides in which language
5 #  the message will be delivered. One can also append the lang code after
6 #  a comma or semicolon behind the mail address to set it explicitely:
7 #  [notify:me@here.org,de] or [notify:you@there.net;eo]
8 #
9 #  Nevertheless English will be used as the default automagically, if
10 #  nothing else was specified, no need to worry about this.
11 #
12 #  additional features:
13 #   * diff inclusion
14 #   * any mail address (works without notify: prefix) on the "GlobalNotify"
15 #     page will receive a notification for any changed page
16 #   * [notify:icq:123456789] - suddenly ICQ.com took the pager service down
17 #
18 #  To include a diff, just set the following constant. Also use it to
19 #  define the minimum number of changed bytes that are necessary to
20 #  result in a notification mail. Only use it with Linux/UNIX.
21
22 define("EWIKI_NOTIFY_WITH_DIFF", 0);       #-- set it to 100 or so
23 define("EWIKI_NOTIFY_SENDER",'ewiki');
24 define("EWIKI_NOTIFY_GLOBAL", "GlobalNotify");
25 define("EWIKI_NOTIFY_DIFF_EXE", "diff");
26 define("EWIKI_NOTIFY_DIFF_PARAMS", " --ignore-case --ignore-space-change");
27
28 #-- glue
29 $ewiki_plugins["edit_hook"][] = "ewiki_notify_edit_hook";
30 $ewiki_plugins["format_source"][] = "ewiki_format_remove_notify";
31 $ewiki_config["interwiki"]["notify"] = "mailto:";
32
33
34 #-- email message text ---------------------------------------------------
35 $ewiki_t["en"]["NOTIFY_SUBJECT"] = '"$id" was changed [notify:...]';
36 $ewiki_t["en"]["NOTIFY_BODY"] = <<<_END_OF_STRING
37 Hi,
38
39 A WikiPage has changed and you requested to be notified when this
40 happens. The changed page was '\$id' and can be found
41 at the following URL:
42 \$link
43
44 To see just the changes in the new version, you can click here:
45 \$diff_link
46
47 To stop messages like this please strip the [notify:...] with your address
48 from the page edit box at \$edit_link
49
50 (\$wiki_title on http://\$server/)
51 \$server_admin
52 _END_OF_STRING;
53
54
55 #-- translation.de
56 $ewiki_t["de"]["NOTIFY_SUBJECT"] = '"$id" wurde geändert [notify:...]';
57 $ewiki_t["de"]["NOTIFY_BODY"] = <<<_END_OF_STRING
58 Hi,
59
60 Eine WikiSeite hat sich geändert, und du wolltest ja unbedingt wissen,
61 wenn das passiert. Die geänderte Seite war '\$id' und
62 ist leicht zu finden unter folgender URL:
63 \$link
64
65 Wenn du diese Benachrichtigungen nicht mehr bekommen willst, solltest du
66 deine [notify:...]-Adresse aus der entsprechenden Edit-Box herauslöschen:
67 \$edit_link
68
69 (\$wiki_title auf http://\$server/)
70 \$server_admin
71 _END_OF_STRING;
72
73
74 #----------------------------------------------------------------------------
75
76
77
78 #-- implementatition
79 function ewiki_notify_edit_hook($id, $data, &$hidden_postdata) {
80
81    global $ewiki_t, $ewiki_plugins;
82    $ret_err = 0;
83
84    if (!isset($_REQUEST["save"])) {
85       return(false);
86    }
87
88    #-- list from current page
89    $mailto = ewiki_notify_links($data["content"], 0);
90
91    #-- add entries from GlobalNotify page/list
92    if ($add = ewiki_db::GET(EWIKI_NOTIFY_GLOBAL)) {
93       ewiki_scan_wikiwords($add["content"], $uu, $strip_emails=false);
94       foreach ($uu as $add=>$stat) {
95          if (strpos($add, "@") && strpos($add, ".")) {
96             $mailto[] = str_replace("notify:", "", $add);
97          }
98       }
99    }
100
101    if (!count($mailto)) {
102       return(false); 
103    }
104
105    #-- generate diff
106    $diff = "";
107    if (EWIKI_NOTIFY_WITH_DIFF && (DIRECTORY_SEPARATOR=="/")) {
108
109       #-- save page versions temporarily as files
110       $fn1 = EWIKI_TMP."/ewiki.tmp.notify.diff.".md5($data["content"]);
111       $fn2 = EWIKI_TMP."/ewiki.tmp.notify.diff.".md5($_REQUEST["content"]);
112       $f = fopen($fn1, "w");
113       fwrite($f, $data["content"]);
114       fclose($f);
115       $f = fopen($fn2, "w");
116       fwrite($f, $_REQUEST["content"]);
117       fclose($f);
118       #-- set mtime of the old one (GNU diff will report it)
119       touch($fn1, $data["lastmodified"]);
120
121       #-- get diff output, rm temp files
122       $diff_exe    = EWIKI_NOTIFY_DIFF_EXE;
123       $diff_params = EWIKI_NOTIFY_DIFF_PARAMS;
124       if ($f = popen("$diff_exe  $diff_params  $fn1 $fn2   2>&1 ", "r")) {
125
126          $diff .= fread($f, 16<<10);
127          pclose($f);
128
129          $diff_failed = !strlen($diff)
130                      || (strpos($diff, "Files ") === 0);
131
132          #-- do not [notify:] if changes were minimal
133          if ((!$diff_failed) && (strlen($diff) < EWIKI_NOTIFY_WITH_DIFF)) {
134 #echo("WikiNotice: no notify, because too few changes (" .strlen($diff)." byte)\n");
135             $ret_err = 1;
136          }
137
138          $diff = "\n\n-----------------------------------------------------------------------------\n\n"
139                . $diff;
140       }
141       else {
142          $diff = "";
143 #echo("WikiWarning: diff failed in notify module\n");
144       }
145
146       unlink($fn1);
147       unlink($fn2);
148
149       if ($ret_err) {
150          return(false);
151       }
152    }
153
154    #-- separate addresses into (TLD) groups
155    $mailto_lang = array(
156    );
157    foreach ($mailto as $m) {
158
159       $lang = "";
160
161       #-- remove lang selection trailer
162       $m = strtok($m, ",");
163       if ($uu = strtok(",")) {
164          $lang = $uu;
165       }
166       $m = strtok($m, ";");
167       if ($uu = strtok(";")) {
168          $lang = $uu;
169       }
170
171       #-- else use TLD as language code
172       if (empty($lang)) {
173          $r = strrpos($m, ".");
174          $lang = substr($m, $r+1);
175       }
176       $lang = trim($lang);
177
178       #-- address mangling
179       $m = trim($m);
180       if (substr($m, 0, 4) == "icq:") {
181          $m = substr($m, 4) . "@pager.icq.com";
182       }
183
184       $mailto_lang[$lang][] = $m;
185    }
186
187    #-- go thru email address groups
188    foreach ($mailto_lang as $lang=>$a_mailto) {
189
190       $pref_langs = array(
191          "$lang", "en"
192       ) + (array)$ewiki_t["languages"];
193
194       ($server = $_SERVER["HTTP_HOST"]) or
195       ($server = $_SERVER["SERVER_NAME"]);
196       $s_4 = "http".($_SERVER['HTTPS'] == "on" ? 's':'')."://" . $server . $_SERVER["REQUEST_URI"];
197       $link = str_replace("edit/$id", "$id", $s_4);
198       $difflink = str_replace("edit/$id", "diff/$id", $s_4);
199
200       $m_text = ewiki_t("NOTIFY_BODY", array(
201          "id" => $id,
202          "link" => $link,
203          "diff_link" => $difflink,
204          "edit_link" => $s_4,
205          "server_admin" => $_SERVER["SERVER_ADMIN"],
206          "server" => $server,
207          "wiki_title" => EWIKI_PAGE_INDEX,
208       ), $pref_langs);
209       $m_text .= $diff;
210
211       $m_from = EWIKI_NOTIFY_SENDER."@$server";
212       $m_subject = ewiki_t("NOTIFY_SUBJECT", array(
213          "id" => $id,
214       ), $pref_langs);
215
216       $m_to = implode(", ", $a_mailto);
217
218       mail($m_to, $m_subject, $m_text, "From: \"$s_2\" <$m_from>\nX-Mailer: ErfurtWiki/".EWIKI_VERSION);
219
220    }
221 }
222
223
224
225 function ewiki_notify_links(&$source, $strip=1) {
226    $links = array();
227    $l = 0;
228    if (strlen($source) > 10)
229    while (($l = @strpos($source, "[notify:", $l)) !== false) {
230       $r = strpos($source, "]", $l);
231       $n = strpos($source, "\n", $l);
232       if ($r && (!$n || ($r<$n))) {
233          $str = substr($source, $l, $r + 1 - $l);
234          if (!strpos("\n", $str)) {
235             $links[] = trim(substr($str, 8, -1));
236             if ($strip) {
237                $source = substr($source, 0, $l) . substr($source, $r + 1);
238             }
239          }
240       }
241       $l++;
242    }
243    return($links);
244 }
245
246
247
248 function ewiki_format_remove_notify(&$source) {
249    ewiki_notify_links($source, 1);
250 }
251
252
253
254 ?>