summaryrefslogtreecommitdiff
path: root/inc
diff options
context:
space:
mode:
authorAndreas Gohr <andi@splitbrain.org>2013-01-26 11:21:39 +0100
committerAndreas Gohr <andi@splitbrain.org>2013-01-26 11:21:39 +0100
commitba56222349781fd8e3938ab18127d46f3c1e0061 (patch)
tree1e39e4e2960462ea06ae55a993512bf18ce4aa25 /inc
parent1285aa3a44c9fdf49bfd8992f33bac068bae8226 (diff)
parentc38b7fab9eeb9456aaf5fe8e4481c3b8569e5644 (diff)
downloadrpg-ba56222349781fd8e3938ab18127d46f3c1e0061.tar.gz
rpg-ba56222349781fd8e3938ab18127d46f3c1e0061.tar.bz2
Merge branch 'subscription' Pull Request #125
* subscription: (25 commits) link directly to subscription management in mails only use mailfromnobody for bulk mails added missing context for list mails readded mailfromnobody to subscription sending correctly escape diffs in HTML mails fixed lists in HTML mails simplified subscription->add() code a bit comment adjusted removed unused vars removed data parameter in subscription_handle_post() fixed tests some reformatting added compatibility function moved registration notification to subscription class fixed merge error in inc/auth.php consolidate more notification code in subscription class minor cleanup initialize new subscriptions with current time fixed subscription management correctly check if subscriptions are enabled ...
Diffstat (limited to 'inc')
-rw-r--r--inc/actions.php22
-rw-r--r--inc/auth.php14
-rw-r--r--inc/changelog.php1
-rw-r--r--inc/common.php85
-rw-r--r--inc/lang/ar/subscr_single.txt2
-rw-r--r--inc/lang/bg/subscr_single.txt2
-rw-r--r--inc/lang/da/subscr_single.txt2
-rw-r--r--inc/lang/de-informal/subscr_single.txt2
-rw-r--r--inc/lang/de/subscr_single.txt2
-rw-r--r--inc/lang/en/subscr_single.txt2
-rw-r--r--inc/lang/eo/subscr_single.txt2
-rw-r--r--inc/lang/he/subscr_single.txt2
-rw-r--r--inc/lang/ia/subscr_single.txt2
-rw-r--r--inc/lang/it/subscr_single.txt2
-rw-r--r--inc/lang/ko/subscr_single.txt2
-rw-r--r--inc/lang/la/subscr_digest.txt2
-rw-r--r--inc/lang/la/subscr_single.txt2
-rw-r--r--inc/lang/no/subscr_digest.txt2
-rw-r--r--inc/lang/no/subscr_list.txt2
-rw-r--r--inc/lang/no/subscr_single.txt2
-rw-r--r--inc/lang/pt/subscr_single.txt2
-rw-r--r--inc/lang/sq/subscr_single.txt2
-rw-r--r--inc/load.php1
-rw-r--r--inc/subscription.php925
24 files changed, 621 insertions, 463 deletions
diff --git a/inc/actions.php b/inc/actions.php
index f65b47451..4083b0454 100644
--- a/inc/actions.php
+++ b/inc/actions.php
@@ -711,21 +711,28 @@ function act_subscription($act){
$target = $params['target'];
$style = $params['style'];
- $data = $params['data'];
$action = $params['action'];
// Perform action.
- if (!subscription_set($_SERVER['REMOTE_USER'], $target, $style, $data)) {
+ $sub = new Subscription();
+ if($action == 'unsubscribe'){
+ $ok = $sub->remove($target, $_SERVER['REMOTE_USER'], $style);
+ }else{
+ $ok = $sub->add($target, $_SERVER['REMOTE_USER'], $style);
+ }
+
+ if($ok) {
+ msg(sprintf($lang["subscr_{$action}_success"], hsc($INFO['userinfo']['name']),
+ prettyprint_id($target)), 1);
+ act_redirect($ID, $act);
+ } else {
throw new Exception(sprintf($lang["subscr_{$action}_error"],
hsc($INFO['userinfo']['name']),
prettyprint_id($target)));
}
- msg(sprintf($lang["subscr_{$action}_success"], hsc($INFO['userinfo']['name']),
- prettyprint_id($target)), 1);
- act_redirect($ID, $act);
// Assure that we have valid data if act_redirect somehow fails.
- $INFO['subscribed'] = get_info_subscribed();
+ $INFO['subscribed'] = $sub->user_subscription();
return 'show';
}
@@ -777,8 +784,7 @@ function subscription_handle_post(&$params) {
$style = null;
}
- $data = in_array($style, array('list', 'digest')) ? time() : null;
- $params = compact('target', 'style', 'data', 'action');
+ $params = compact('target', 'style', 'action');
}
//Setup VIM: ex: et ts=2 :
diff --git a/inc/auth.php b/inc/auth.php
index c68a699fe..c4f1dcf2b 100644
--- a/inc/auth.php
+++ b/inc/auth.php
@@ -780,23 +780,19 @@ function register() {
return false;
}
- // create substitutions for use in notification email
- $substitutions = array(
- 'NEWUSER' => $login,
- 'NEWNAME' => $fullname,
- 'NEWEMAIL' => $email,
- );
+ // send notification about the new user
+ $subscription = new Subscription();
+ $subscription->send_register($login, $fullname, $email);
+ // are we done?
if(!$conf['autopasswd']) {
msg($lang['regsuccess2'], 1);
- notify('', 'register', '', $login, false, $substitutions);
return true;
}
- // autogenerated password? then send him the password
+ // autogenerated password? then send password to user
if(auth_sendPassword($login, $pass)) {
msg($lang['regsuccess'], 1);
- notify('', 'register', '', $login, false, $substitutions);
return true;
} else {
msg($lang['regmailfail'], -1);
diff --git a/inc/changelog.php b/inc/changelog.php
index 688aebfd6..9768fea51 100644
--- a/inc/changelog.php
+++ b/inc/changelog.php
@@ -258,6 +258,7 @@ function getRecentsSince($from,$to=null,$ns='',$flags=0){
} else {
$lines = @file($conf['changelog']);
}
+ if(!$lines) return $recent;
// we start searching at the end of the list
$lines = array_reverse($lines);
diff --git a/inc/common.php b/inc/common.php
index 3c40a47dc..bc49e76b2 100644
--- a/inc/common.php
+++ b/inc/common.php
@@ -107,9 +107,11 @@ function pageinfo() {
$info['isadmin'] = false;
$info['ismanager'] = false;
if(isset($_SERVER['REMOTE_USER'])) {
+ $sub = new Subscription();
+
$info['userinfo'] = $USERINFO;
$info['perm'] = auth_quickaclcheck($ID);
- $info['subscribed'] = get_info_subscribed();
+ $info['subscribed'] = $sub->user_subscription();
$info['client'] = $_SERVER['REMOTE_USER'];
if($info['perm'] == AUTH_ADMIN) {
@@ -320,15 +322,13 @@ function idfilter($id, $ue = true) {
if($conf['useslash'] && $conf['userewrite']) {
$id = strtr($id, ':', '/');
} elseif(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' &&
- $conf['userewrite'] &&
- strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') === false
+ $conf['userewrite']
) {
$id = strtr($id, ':', ';');
}
if($ue) {
$id = rawurlencode($id);
$id = str_replace('%3A', ':', $id); //keep as colon
- $id = str_replace('%3B', ';', $id); //keep as semicolon
$id = str_replace('%2F', '/', $id); //keep as slash
}
return $id;
@@ -1105,90 +1105,31 @@ function saveOldRevision($id) {
* @author Andreas Gohr <andi@splitbrain.org>
*/
function notify($id, $who, $rev = '', $summary = '', $minor = false, $replace = array()) {
- global $lang;
global $conf;
- global $INFO;
- global $DIFF_INLINESTYLES;
// decide if there is something to do, eg. whom to mail
if($who == 'admin') {
if(empty($conf['notify'])) return false; //notify enabled?
- $text = rawLocale('mailtext');
- $to = $conf['notify'];
- $bcc = '';
+ $tpl = 'mailtext';
+ $to = $conf['notify'];
} elseif($who == 'subscribers') {
- if(!$conf['subscribers']) return false; //subscribers enabled?
+ if(!actionOK('subscribe')) return false; //subscribers enabled?
if($conf['useacl'] && $_SERVER['REMOTE_USER'] && $minor) return false; //skip minors
$data = array('id' => $id, 'addresslist' => '', 'self' => false);
trigger_event(
'COMMON_NOTIFY_ADDRESSLIST', $data,
- 'subscription_addresslist'
+ array(new Subscription(), 'notifyaddresses')
);
- $bcc = $data['addresslist'];
- if(empty($bcc)) return false;
- $to = '';
- $text = rawLocale('subscr_single');
- } elseif($who == 'register') {
- if(empty($conf['registernotify'])) return false;
- $text = rawLocale('registermail');
- $to = $conf['registernotify'];
- $bcc = '';
+ $to = $data['addresslist'];
+ if(empty($to)) return false;
+ $tpl = 'subscr_single';
} else {
return false; //just to be safe
}
- // prepare replacements (keys not set in hrep will be taken from trep)
- $trep = array(
- 'NEWPAGE' => wl($id, '', true, '&'),
- 'PAGE' => $id,
- 'SUMMARY' => $summary
- );
- $trep = array_merge($trep, $replace);
- $hrep = array();
-
// prepare content
- if($who == 'register') {
- $subject = $lang['mail_new_user'].' '.$summary;
- } elseif($rev) {
- $subject = $lang['mail_changed'].' '.$id;
- $trep['OLDPAGE'] = wl($id, "rev=$rev", true, '&');
- $old_content = rawWiki($id, $rev);
- $new_content = rawWiki($id);
- $df = new Diff(explode("\n", $old_content),
- explode("\n", $new_content));
- $dformat = new UnifiedDiffFormatter();
- $tdiff = $dformat->format($df);
-
- $DIFF_INLINESTYLES = true;
- $hdf = new Diff(explode("\n", hsc($old_content)),
- explode("\n", hsc($new_content)));
- $dformat = new InlineDiffFormatter();
- $hdiff = $dformat->format($hdf);
- $hdiff = '<table>'.$hdiff.'</table>';
- $DIFF_INLINESTYLES = false;
- } else {
- $subject = $lang['mail_newpage'].' '.$id;
- $trep['OLDPAGE'] = '---';
- $tdiff = rawWiki($id);
- $hdiff = nl2br(hsc($tdiff));
- }
- $trep['DIFF'] = $tdiff;
- $hrep['DIFF'] = $hdiff;
-
- // send mail
- $mail = new Mailer();
- $mail->to($to);
- $mail->bcc($bcc);
- $mail->subject($subject);
- $mail->setBody($text, $trep, $hrep);
- if($who == 'subscribers') {
- $mail->setHeader(
- 'List-Unsubscribe',
- '<'.wl($id, array('do'=> 'subscribe'), true, '&').'>',
- false
- );
- }
- return $mail->send();
+ $subscription = new Subscription();
+ return $subscription->send_diff($to, $tpl, $id, $rev, $summary);
}
/**
diff --git a/inc/lang/ar/subscr_single.txt b/inc/lang/ar/subscr_single.txt
index 5c62aeaeb..611688415 100644
--- a/inc/lang/ar/subscr_single.txt
+++ b/inc/lang/ar/subscr_single.txt
@@ -15,7 +15,7 @@
لإلغاء إشعارات الصفحة,لُج الويكي في
@DOKUWIKIURL@ ثم زُر
-@NEWPAGE@
+@SUBSCRIBE@
وألغ الاشتراك من تغييرات الصفحة و/أو النطاق.
--
diff --git a/inc/lang/bg/subscr_single.txt b/inc/lang/bg/subscr_single.txt
index 7b26f8e96..a74a21fb8 100644
--- a/inc/lang/bg/subscr_single.txt
+++ b/inc/lang/bg/subscr_single.txt
@@ -14,7 +14,7 @@
Нова версия: @NEWPAGE@
Ако желаете да прекратите уведомяването за страницата трябва да се впишете на адрес @DOKUWIKIURL@, да посетите
-@NEWPAGE@
+@SUBSCRIBE@
и да прекратите абонамента за промени по страницата или именното пространство.
--
diff --git a/inc/lang/da/subscr_single.txt b/inc/lang/da/subscr_single.txt
index 64b14588c..cdc554513 100644
--- a/inc/lang/da/subscr_single.txt
+++ b/inc/lang/da/subscr_single.txt
@@ -15,7 +15,7 @@ Ny Revision: @NEWPAGE@
For at slå side notifikationer fra, skal du logge ind på
@DOKUWIKIURL@ og besøge
-@NEWPAGE@
+@SUBSCRIBE@
og slå abonnoment for side / navnerum ændringer fra.
--
diff --git a/inc/lang/de-informal/subscr_single.txt b/inc/lang/de-informal/subscr_single.txt
index 3c557bc17..6e3f58b9f 100644
--- a/inc/lang/de-informal/subscr_single.txt
+++ b/inc/lang/de-informal/subscr_single.txt
@@ -15,7 +15,7 @@ Neue Revision: @NEWPAGE@
Um das Abonnement für diese Seite aufzulösen, melde dich im Wiki an
@DOKUWIKIURL@, besuche dann
-@NEWPAGE@
+@SUBSCRIBE@
und klicke auf den Link 'Aboverwaltung'.
--
diff --git a/inc/lang/de/subscr_single.txt b/inc/lang/de/subscr_single.txt
index f3e1cd393..da9914e50 100644
--- a/inc/lang/de/subscr_single.txt
+++ b/inc/lang/de/subscr_single.txt
@@ -15,7 +15,7 @@ Neue Revision: @NEWPAGE@
Um das Abonnement für diese Seite aufzulösen, melden Sie sich im Wiki an
@DOKUWIKIURL@, besuchen dann
-@NEWPAGE@
+@SUBSCRIBE@
und klicken auf die Taste 'Aboverwaltung'.
--
diff --git a/inc/lang/en/subscr_single.txt b/inc/lang/en/subscr_single.txt
index 673c4c32a..0bc310e04 100644
--- a/inc/lang/en/subscr_single.txt
+++ b/inc/lang/en/subscr_single.txt
@@ -15,7 +15,7 @@ New Revision: @NEWPAGE@
To cancel the page notifications, log into the wiki at
@DOKUWIKIURL@ then visit
-@NEWPAGE@
+@SUBSCRIBE@
and unsubscribe page and/or namespace changes.
--
diff --git a/inc/lang/eo/subscr_single.txt b/inc/lang/eo/subscr_single.txt
index 431fd0251..e4847e8ab 100644
--- a/inc/lang/eo/subscr_single.txt
+++ b/inc/lang/eo/subscr_single.txt
@@ -15,7 +15,7 @@ Nova versio: @NEWPAGE@
Por nuligi la paĝinformojn, ensalutu la vikion ĉe
@DOKUWIKIURL@, poste iru al
-@NEWPAGE@
+@SUBSCRIBE@
kaj malabonu la paĝajn kaj/aŭ nomspacajn ŝanĝojn.
--
diff --git a/inc/lang/he/subscr_single.txt b/inc/lang/he/subscr_single.txt
index 123b186c8..78b551e2f 100644
--- a/inc/lang/he/subscr_single.txt
+++ b/inc/lang/he/subscr_single.txt
@@ -14,7 +14,7 @@
לביטול התרעות בנוגע לעמוד, יש להיכנס לאתר הוויקי בכתובת
@DOKUWIKIURL@ ואז לבקר בדף
-@NEWPAGE@
+@SUBSCRIBE@
ולבטל את המינוי לקבלת שינויים בדף ו/או במרחב השם.
--
diff --git a/inc/lang/ia/subscr_single.txt b/inc/lang/ia/subscr_single.txt
index 3d6ef7103..445df197c 100644
--- a/inc/lang/ia/subscr_single.txt
+++ b/inc/lang/ia/subscr_single.txt
@@ -15,7 +15,7 @@ Version nove: @NEWPAGE@
Pro cancellar le notificationes de paginas, aperi un session al wiki a
@DOKUWIKIURL@ postea visita
-@NEWPAGE@
+@SUBSCRIBE@
e cancella tu subscription al modificationes in paginas e/o spatios de nomines.
--
diff --git a/inc/lang/it/subscr_single.txt b/inc/lang/it/subscr_single.txt
index 8cde8ea0f..a8649a4ef 100644
--- a/inc/lang/it/subscr_single.txt
+++ b/inc/lang/it/subscr_single.txt
@@ -15,7 +15,7 @@ Nuova revisione: @NEWPAGE@
Per non ricevere più queste notifiche, collegati al
wiki all'indirizzo @DOKUWIKIURL@ e poi visita
-@NEWPAGE@
+@SUBSCRIBE@
e rimuovi la sottoscrizione alle modifiche della
pagina o categoria.
diff --git a/inc/lang/ko/subscr_single.txt b/inc/lang/ko/subscr_single.txt
index 6bd1885e6..2679db393 100644
--- a/inc/lang/ko/subscr_single.txt
+++ b/inc/lang/ko/subscr_single.txt
@@ -14,7 +14,7 @@
새 버전 : @NEWPAGE@
이 문서의 알림을 취소하려면, @DOKUWIKIURL@에 로그인한 뒤
-@NEWPAGE@ 문서를 방문하여 문서나 이름공간의 구독을 취소하세요.
+@SUBSCRIBE@ 문서를 방문하여 문서나 이름공간의 구독을 취소하세요.
--
@DOKUWIKIURL@의 DokuWiki가 자동으로 만들어낸 메일입니다. \ No newline at end of file
diff --git a/inc/lang/la/subscr_digest.txt b/inc/lang/la/subscr_digest.txt
index 629213359..32d378a7e 100644
--- a/inc/lang/la/subscr_digest.txt
+++ b/inc/lang/la/subscr_digest.txt
@@ -12,7 +12,7 @@ Noua recensio: @NEWPAGE@
Ut paginae adnotationes deleas, in uicem ineas in
@DOKUWIKIURL@, deinde uideas
-@NEWPAGE@
+@SUBSCRIBE@
et paginarum generum optiones mutes.
--
diff --git a/inc/lang/la/subscr_single.txt b/inc/lang/la/subscr_single.txt
index 7839791ea..14285014c 100644
--- a/inc/lang/la/subscr_single.txt
+++ b/inc/lang/la/subscr_single.txt
@@ -15,7 +15,7 @@ Noua recensio: @NEWPAGE@
Ut paginae adnotationes deleas, in uicem ineas in
@DOKUWIKIURL@, deinde uideas
-@NEWPAGE@
+@SUBSCRIBE@
et paginarum et\aut generum optiones mutasa.
--
diff --git a/inc/lang/no/subscr_digest.txt b/inc/lang/no/subscr_digest.txt
index 6afd0cc5c..670d39d32 100644
--- a/inc/lang/no/subscr_digest.txt
+++ b/inc/lang/no/subscr_digest.txt
@@ -12,7 +12,7 @@ Ny versjon: @NEWPAGE@
For å avslutte varslingen, logg inn på
@DOKUWIKIURL@ og gå til
-@NEWPAGE@
+@SUBSCRIBE@
og avslutt abonnementet på endringer av siden eller i navnerommet.
--
diff --git a/inc/lang/no/subscr_list.txt b/inc/lang/no/subscr_list.txt
index 72cd307cb..860d88d2a 100644
--- a/inc/lang/no/subscr_list.txt
+++ b/inc/lang/no/subscr_list.txt
@@ -9,7 +9,7 @@ Her er endringene:
For å avslutte varslinga, logg inn på
@DOKUWIKIURL@ og gå til
-@NEWPAGE@
+@SUBSCRIBE@
og avslutt abonnementet på endringer av sida eller i navnerommet.
--
diff --git a/inc/lang/no/subscr_single.txt b/inc/lang/no/subscr_single.txt
index 25296da58..b26b3a879 100644
--- a/inc/lang/no/subscr_single.txt
+++ b/inc/lang/no/subscr_single.txt
@@ -15,7 +15,7 @@ Ny versjon: @NEWPAGE@
For å avslutte varslingen, logg inn på
@DOKUWIKIURL@, gå til
-@NEWPAGE@
+@SUBSCRIBE@
og avslutt abonnementet på endringer av siden eller i navnerommet.
--
diff --git a/inc/lang/pt/subscr_single.txt b/inc/lang/pt/subscr_single.txt
index 1187b5911..469c6bfb1 100644
--- a/inc/lang/pt/subscr_single.txt
+++ b/inc/lang/pt/subscr_single.txt
@@ -15,7 +15,7 @@ Revisão Nova: @NEWPAGE@
Para cancelar as notificações de página, inicie sessão no wiki em
@DOKUWIKIURL@, visite
-@NEWPAGE@
+@SUBSCRIBE@
e des-subscreva às alterações de página e/ou espaço de nome.
--
diff --git a/inc/lang/sq/subscr_single.txt b/inc/lang/sq/subscr_single.txt
index 90520be4f..df28ee176 100644
--- a/inc/lang/sq/subscr_single.txt
+++ b/inc/lang/sq/subscr_single.txt
@@ -15,7 +15,7 @@ Rishikimi i ri: @NEWPAGE@
Për të fshirë lajmërimet e faqes, hyni në wiki tek
@DOKUWIKIURL@ dhe pastaj vizitoni
-@NEWPAGE@
+@SUBSCRIBE@
dhe fshini ndryshimet e faqes dhe/ose hapësirës së emrit.
--
diff --git a/inc/load.php b/inc/load.php
index 49c307054..7fd9fc9d0 100644
--- a/inc/load.php
+++ b/inc/load.php
@@ -82,6 +82,7 @@ function load_autoload($name){
'Mailer' => DOKU_INC.'inc/Mailer.class.php',
'RemoteAPI' => DOKU_INC.'inc/remote.php',
'RemoteAPICore' => DOKU_INC.'inc/RemoteAPICore.php',
+ 'Subscription' => DOKU_INC.'inc/subscription.php',
'DokuWiki_Action_Plugin' => DOKU_PLUGIN.'action.php',
'DokuWiki_Admin_Plugin' => DOKU_PLUGIN.'admin.php',
diff --git a/inc/subscription.php b/inc/subscription.php
index 6b201c266..62cfd1509 100644
--- a/inc/subscription.php
+++ b/inc/subscription.php
@@ -1,414 +1,627 @@
<?php
/**
- * Utilities for handling (email) subscriptions
- *
- * The public interface of this file consists of the functions
- * - subscription_find
- * - subscription_send_digest
- * - subscription_send_list
- * - subscription_set
- * - get_info_subscribed
- * - subscription_addresslist
- * - subscription_lock
- * - subscription_unlock
+ * Class for handling (email) subscriptions
*
* @author Adrian Lang <lang@cosmocode.de>
+ * @author Andreas Gohr <andi@splitbrain.org>
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
*/
+class Subscription {
-/**
- * Get the name of the metafile tracking subscriptions to target page or
- * namespace
- *
- * @author Adrian Lang <lang@cosmocode.de>
- *
- * @param string $id The target page or namespace, specified by id; Namespaces
- * are identified by appending a colon.
- * @return string
- */
-function subscription_filename($id) {
- $meta_fname = '.mlist';
- if ((substr($id, -1, 1) === ':')) {
- $meta_froot = getNS($id);
- $meta_fname = '/' . $meta_fname;
- } else {
- $meta_froot = $id;
+ /**
+ * Check if subscription system is enabled
+ *
+ * @return bool
+ */
+ public function isenabled() {
+ return actionOK('subscribe');
}
- return metaFN((string) $meta_froot, $meta_fname);
-}
-
-/**
- * Lock subscription info for an ID
- *
- * @author Adrian Lang <lang@cosmocode.de>
- * @param string $id The target page or namespace, specified by id; Namespaces
- * are identified by appending a colon.
- * @return string
- */
-function subscription_lock_filename ($id){
- global $conf;
- return $conf['lockdir'].'/_subscr_' . md5($id) . '.lock';
-}
-/**
- * Creates a lock file for writing subscription data
- *
- * @todo add lock time parameter to io_lock() and use this instead
- * @param $id
- * @return bool
- */
-function subscription_lock($id) {
- global $conf;
- $lock = subscription_lock_filename($id);
-
- if (is_dir($lock) && time()-@filemtime($lock) > 60*5) {
- // looks like a stale lock - remove it
- @rmdir($lock);
+ /**
+ * Return the subscription meta file for the given ID
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ *
+ * @param string $id The target page or namespace, specified by id; Namespaces
+ * are identified by appending a colon.
+ * @return string
+ */
+ protected function file($id) {
+ $meta_fname = '.mlist';
+ if((substr($id, -1, 1) === ':')) {
+ $meta_froot = getNS($id);
+ $meta_fname = '/'.$meta_fname;
+ } else {
+ $meta_froot = $id;
+ }
+ return metaFN((string) $meta_froot, $meta_fname);
}
- // try creating the lock directory
- if (!@mkdir($lock,$conf['dmode'])) {
- return false;
- }
+ /**
+ * Lock subscription info
+ *
+ * We don't use io_lock() her because we do not wait for the lock and use a larger stale time
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ * @param string $id The target page or namespace, specified by id; Namespaces
+ * are identified by appending a colon.
+ * @return bool true, if you got a succesful lock
+ */
+ protected function lock($id) {
+ global $conf;
- if($conf['dperm']) chmod($lock, $conf['dperm']);
- return true;
-}
+ $lock = $conf['lockdir'].'/_subscr_'.md5($id).'.lock';
-/**
- * Unlock subscription info for an ID
- *
- * @author Adrian Lang <lang@cosmocode.de>
- * @param string $id The target page or namespace, specified by id; Namespaces
- * are identified by appending a colon.
- * @return bool
- */
-function subscription_unlock($id) {
- $lockf = subscription_lock_filename($id);
- return @rmdir($lockf);
-}
+ if(is_dir($lock) && time() - @filemtime($lock) > 60 * 5) {
+ // looks like a stale lock - remove it
+ @rmdir($lock);
+ }
-/**
- * Set subscription information
- *
- * Allows to set subscription information for permanent storage in meta files.
- * Subscriptions consist of a target object, a subscribing user, a subscribe
- * style and optional data.
- * A subscription may be deleted by specifying an empty subscribe style.
- * Only one subscription per target and user is allowed.
- * The function returns false on error, otherwise true. Note that no error is
- * returned if a subscription should be deleted but the user is not subscribed
- * and the subscription meta file exists.
- *
- * @author Adrian Lang <lang@cosmocode.de>
- *
- * @param string $user The subscriber or unsubscriber
- * @param string $page The target object (page or namespace), specified by
- * id; Namespaces are identified by a trailing colon.
- * @param string $style The subscribe style; DokuWiki currently implements
- * “every”, “digest”, and “list”.
- * @param string $data An optional data blob
- * @param bool $overwrite Whether an existing subscription may be overwritten
- * @return bool
- */
-function subscription_set($user, $page, $style, $data = null,
- $overwrite = false) {
- global $lang;
- if (is_null($style)) {
- // Delete subscription.
- $file = subscription_filename($page);
- if (!@file_exists($file)) {
- msg(sprintf($lang['subscr_not_subscribed'], $user,
- prettyprint_id($page)), -1);
+ // try creating the lock directory
+ if(!@mkdir($lock, $conf['dmode'])) {
return false;
}
- // io_deleteFromFile does not return false if no line matched.
- return io_deleteFromFile($file,
- subscription_regex(array('user' => auth_nameencode($user))),
- true);
+ if($conf['dperm']) chmod($lock, $conf['dperm']);
+ return true;
}
- // Delete subscription if one exists and $overwrite is true. If $overwrite
- // is false, fail.
- $subs = subscription_find($page, array('user' => $user));
- if (count($subs) > 0 && isset($subs[$page])) {
- if (!$overwrite) {
- msg(sprintf($lang['subscr_already_subscribed'], $user,
- prettyprint_id($page)), -1);
- return false;
+ /**
+ * Unlock subscription info
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ * @param string $id The target page or namespace, specified by id; Namespaces
+ * are identified by appending a colon.
+ * @return bool
+ */
+ protected function unlock($id) {
+ global $conf;
+ $lock = $conf['lockdir'].'/_subscr_'.md5($id).'.lock';
+ return @rmdir($lock);
+ }
+
+ /**
+ * Construct a regular expression for parsing a subscription definition line
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string|array $user
+ * @param string|array $style
+ * @param string|array $data
+ * @return string complete regexp including delimiters
+ * @throws Exception when no data is passed
+ */
+ protected function buildregex($user = null, $style = null, $data = null) {
+ // always work with arrays
+ $user = (array) $user;
+ $style = (array) $style;
+ $data = (array) $data;
+
+ // clean
+ $user = array_filter(array_map('trim', $user));
+ $style = array_filter(array_map('trim', $style));
+ $data = array_filter(array_map('trim', $data));
+
+ // user names are encoded
+ $user = array_map('auth_nameencode', $user);
+
+ // quote
+ $user = array_map('preg_quote_cb', $user);
+ $style = array_map('preg_quote_cb', $style);
+ $data = array_map('preg_quote_cb', $data);
+
+ // join
+ $user = join('|', $user);
+ $style = join('|', $style);
+ $data = join('|', $data);
+
+ // any data at all?
+ if($user.$style.$data === '') throw new Exception('no data passed');
+
+ // replace empty values, set which ones are optional
+ $sopt = '';
+ $dopt = '';
+ if($user === '') {
+ $user = '\S+';
}
- // Fail if deletion failed, else continue.
- if (!subscription_set($user, $page, null)) {
- return false;
+ if($style === '') {
+ $style = '\S+';
+ $sopt = '?';
+ }
+ if($data === '') {
+ $data = '\S+';
+ $dopt = '?';
}
- }
- $file = subscription_filename($page);
- $content = auth_nameencode($user) . ' ' . $style;
- if (!is_null($data)) {
- $content .= ' ' . $data;
+ // assemble
+ return "/^($user)(?:\\s+($style))$sopt(?:\\s+($data))$dopt$/";
}
- return io_saveFile($file, $content . "\n", true);
-}
-/**
- * Recursively search for matching subscriptions
- *
- * This function searches all relevant subscription files for a page or
- * namespace.
- *
- * @author Adrian Lang <lang@cosmocode.de>
- * @see function subscription_regex for $pre documentation
- *
- * @param string $page The target object’s (namespace or page) id
- * @param array $pre A hash of predefined values
- * @return array
- */
-function subscription_find($page, $pre) {
- // Construct list of files which may contain relevant subscriptions.
- $filenames = array(':' => subscription_filename(':'));
- do {
- $filenames[$page] = subscription_filename($page);
- $page = getNS(rtrim($page, ':')) . ':';
- } while ($page !== ':');
-
- // Handle files.
- $matches = array();
- foreach ($filenames as $cur_page => $filename) {
- if (!@file_exists($filename)) {
- continue;
- }
- $subscriptions = file($filename);
- foreach ($subscriptions as $subscription) {
- if (strpos($subscription, ' ') === false) {
- // This is an old subscription file.
- $subscription = trim($subscription) . " every\n";
- }
+ /**
+ * Recursively search for matching subscriptions
+ *
+ * This function searches all relevant subscription files for a page or
+ * namespace.
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ *
+ * @param string $page The target object’s (namespace or page) id
+ * @param string|array $user
+ * @param string|array $style
+ * @param string|array $data
+ * @return array
+ */
+ public function subscribers($page, $user = null, $style = null, $data = null) {
+ if(!$this->isenabled()) return array();
- list($user, $rest) = explode(' ', $subscription, 2);
- $subscription = rawurldecode($user) . " " . $rest;
+ // Construct list of files which may contain relevant subscriptions.
+ $files = array(':' => $this->file(':'));
+ do {
+ $files[$page] = $this->file($page);
+ $page = getNS(rtrim($page, ':')).':';
+ } while($page !== ':');
- if (preg_match(subscription_regex($pre), $subscription,
- $line_matches) === 0) {
- continue;
- }
- $match = array_slice($line_matches, 1);
- if (!isset($matches[$cur_page])) {
- $matches[$cur_page] = array();
+ $re = $this->buildregex($user, $style, $data);
+
+ // Handle files.
+ $result = array();
+ foreach($files as $target => $file) {
+ if(!@file_exists($file)) continue;
+
+ $lines = file($file);
+ foreach($lines as $line) {
+ // fix old style subscription files
+ if(strpos($line, ' ') === false) $line = trim($line)." every\n";
+
+ // check for matching entries
+ if(!preg_match($re, $line, $m)) continue;
+
+ $u = rawurldecode($m[1]); // decode the user name
+ if(!isset($result[$target])) $result[$target] = array();
+ $result[$target][$u] = array($m[2], $m[3]); // add to result
}
- $matches[$cur_page][] = $match;
}
+ return array_reverse($result);
}
- return array_reverse($matches);
-}
-/**
- * Get data for $INFO['subscribed']
- *
- * $INFO['subscribed'] is either false if no subscription for the current page
- * and user is in effect. Else it contains an array of arrays with the fields
- * “target”, “style”, and optionally “data”.
- *
- * @author Adrian Lang <lang@cosmocode.de>
- */
-function get_info_subscribed() {
- global $ID;
- global $conf;
- if (!$conf['subscribers']) {
- return false;
+ /**
+ * Adds a new subscription for the given page or namespace
+ *
+ * This will automatically overwrite any existent subscription for the given user on this
+ * *exact* page or namespace. It will *not* modify any subscription that may exist in higher namespaces.
+ *
+ * @param string $id The target page or namespace, specified by id; Namespaces
+ * are identified by appending a colon.
+ * @param string $user
+ * @param string $style
+ * @param string $data
+ * @throws Exception when user or style is empty
+ * @return bool
+ */
+ public function add($id, $user, $style, $data = '') {
+ if(!$this->isenabled()) return false;
+
+ // delete any existing subscription
+ $this->remove($id, $user);
+
+ $user = auth_nameencode(trim($user));
+ $style = trim($style);
+ $data = trim($data);
+
+ if(!$user) throw new Exception('no subscription user given');
+ if(!$style) throw new Exception('no subscription style given');
+ if(!$data) $data = time(); //always add current time for new subscriptions
+
+ $line = "$user $style $data\n";
+ $file = $this->file($id);
+ return io_saveFile($file, $line, true);
}
- $subs = subscription_find($ID, array('user' => $_SERVER['REMOTE_USER']));
- if (count($subs) === 0) {
- return false;
+ /**
+ * Removes a subscription for the given page or namespace
+ *
+ * This removes all subscriptions matching the given criteria on the given page or
+ * namespace. It will *not* modify any subscriptions that may exist in higher
+ * namespaces.
+ *
+ * @param string $id The target object’s (namespace or page) id
+ * @param string|array $user
+ * @param string|array $style
+ * @param string|array $data
+ * @return bool
+ */
+ public function remove($id, $user = null, $style = null, $data = null) {
+ if(!$this->isenabled()) return false;
+
+ $file = $this->file($id);
+ if(!file_exists($file)) return true;
+
+ $re = $this->buildregex($user, $style, $data);
+ return io_deleteFromFile($file, $re, true);
}
- $_ret = array();
- foreach ($subs as $target => $subs_data) {
- $new = array('target' => $target,
- 'style' => $subs_data[0][0]);
- if (count($subs_data[0]) > 1) {
- $new['data'] = $subs_data[0][1];
+ /**
+ * Get data for $INFO['subscribed']
+ *
+ * $INFO['subscribed'] is either false if no subscription for the current page
+ * and user is in effect. Else it contains an array of arrays with the fields
+ * “target”, “style”, and optionally “data”.
+ *
+ * @param string $id Page ID, defaults to global $ID
+ * @param string $user User, defaults to $_SERVER['REMOTE_USER']
+ * @return array
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+ function user_subscription($id = '', $user = '') {
+ if(!$this->isenabled()) return false;
+
+ global $ID;
+ if(!$id) $id = $ID;
+ if(!$user) $user = $_SERVER['REMOTE_USER'];
+
+ $subs = $this->subscribers($id, $user);
+ if(!count($subs)) return false;
+
+ $result = array();
+ foreach($subs as $target => $info) {
+ $result[] = array(
+ 'target' => $target,
+ 'style' => $info[$user][0],
+ 'data' => $info[$user][1]
+ );
}
- $_ret[] = $new;
+
+ return $result;
}
- return $_ret;
-}
+ /**
+ * Send digest and list subscriptions
+ *
+ * This sends mails to all subscribers that have a subscription for namespaces above
+ * the given page if the needed $conf['subscribe_time'] has passed already.
+ *
+ * This function is called form lib/exe/indexer.php
+ *
+ * @param string $page
+ * @return int number of sent mails
+ */
+ public function send_bulk($page) {
+ if(!$this->isenabled()) return 0;
-/**
- * Construct a regular expression parsing a subscription definition line
- *
- * @author Adrian Lang <lang@cosmocode.de>
- *
- * @param array $pre A hash of predefined values; “user”, “style”, and
- * “data” may be set to limit the results to
- * subscriptions matching these parameters. If
- * “escaped” is true, these fields are inserted into the
- * regular expression without escaping.
- *
- * @return string complete regexp including delimiters
- */
-function subscription_regex($pre = array()) {
- if (!isset($pre['escaped']) || $pre['escaped'] === false) {
- $pre = array_map('preg_quote_cb', $pre);
+ /** @var auth_basic $auth */
+ global $auth;
+ global $conf;
+ global $USERINFO;
+ $count = 0;
+
+ $subscriptions = $this->subscribers($page, null, array('digest', 'list'));
+
+ // remember current user info
+ $olduinfo = $USERINFO;
+ $olduser = $_SERVER['REMOTE_USER'];
+
+ foreach($subscriptions as $target => $users) {
+ if(!$this->lock($target)) continue;
+
+ foreach($users as $user => $info) {
+ list($style, $lastupdate) = $info;
+
+ $lastupdate = (int) $lastupdate;
+ if($lastupdate + $conf['subscribe_time'] > time()) {
+ // Less than the configured time period passed since last
+ // update.
+ continue;
+ }
+
+ // Work as the user to make sure ACLs apply correctly
+ $USERINFO = $auth->getUserData($user);
+ $_SERVER['REMOTE_USER'] = $user;
+ if($USERINFO === false) continue;
+ if(!$USERINFO['mail']) continue;
+
+ if(substr($target, -1, 1) === ':') {
+ // subscription target is a namespace, get all changes within
+ $changes = getRecentsSince($lastupdate, null, getNS($target));
+ } else {
+ // single page subscription, check ACL ourselves
+ if(auth_quickaclcheck($target) < AUTH_READ) continue;
+ $meta = p_get_metadata($target);
+ $changes = array($meta['last_change']);
+ }
+
+ // Filter out pages only changed in small and own edits
+ $change_ids = array();
+ foreach($changes as $rev) {
+ $n = 0;
+ while(!is_null($rev) && $rev['date'] >= $lastupdate &&
+ ($_SERVER['REMOTE_USER'] === $rev['user'] ||
+ $rev['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT)) {
+ $rev = getRevisions($rev['id'], $n++, 1);
+ $rev = (count($rev) > 0) ? $rev[0] : null;
+ }
+
+ if(!is_null($rev) && $rev['date'] >= $lastupdate) {
+ // Some change was not a minor one and not by myself
+ $change_ids[] = $rev['id'];
+ }
+ }
+
+ // send it
+ if($style === 'digest') {
+ foreach($change_ids as $change_id) {
+ $this->send_digest(
+ $USERINFO['mail'], $change_id,
+ $lastupdate
+ );
+ $count++;
+ }
+ } elseif($style === 'list') {
+ $this->send_list($USERINFO['mail'], $change_ids, $target);
+ $count++;
+ }
+ // TODO: Handle duplicate subscriptions.
+
+ // Update notification time.
+ $this->add($target, $user, $style, time());
+ }
+ $this->unlock($target);
+ }
+
+ // restore current user info
+ $USERINFO = $olduinfo;
+ $_SERVER['REMOTE_USER'] = $olduser;
+ return $count;
}
- foreach (array('user', 'style', 'data') as $key) {
- if (!isset($pre[$key])) {
- $pre[$key] = '(\S+)';
+
+ /**
+ * Send the diff for some page change
+ *
+ * @param string $subscriber_mail The target mail address
+ * @param string $template Mail template ('subscr_digest', 'subscr_single', 'mailtext', ...)
+ * @param string $id Page for which the notification is
+ * @param int|null $rev Old revision if any
+ * @param string $summary Change summary if any
+ * @return bool true if successfully sent
+ */
+ public function send_diff($subscriber_mail, $template, $id, $rev = null, $summary = '') {
+ global $DIFF_INLINESTYLES;
+
+ // prepare replacements (keys not set in hrep will be taken from trep)
+ $trep = array(
+ 'PAGE' => $id,
+ 'NEWPAGE' => wl($id, '', true, '&'),
+ 'SUMMARY' => $summary,
+ 'SUBSCRIBE' => wl($id, array('do' => 'subscribe'), true, '&')
+ );
+ $hrep = array();
+
+ if($rev) {
+ $subject = 'changed';
+ $trep['OLDPAGE'] = wl($id, "rev=$rev", true, '&');
+
+ $old_content = rawWiki($id, $rev);
+ $new_content = rawWiki($id);
+
+ $df = new Diff(explode("\n", $old_content),
+ explode("\n", $new_content));
+ $dformat = new UnifiedDiffFormatter();
+ $tdiff = $dformat->format($df);
+
+ $DIFF_INLINESTYLES = true;
+ $df = new Diff(explode("\n", hsc($old_content)),
+ explode("\n", hsc($new_content)));
+ $dformat = new InlineDiffFormatter();
+ $hdiff = $dformat->format($df);
+ $hdiff = '<table>'.$hdiff.'</table>';
+ $DIFF_INLINESTYLES = false;
+ } else {
+ $subject = 'newpage';
+ $trep['OLDPAGE'] = '---';
+ $tdiff = rawWiki($id);
+ $hdiff = nl2br(hsc($tdiff));
}
+
+ $trep['DIFF'] = $tdiff;
+ $hrep['DIFF'] = $hdiff;
+
+ return $this->send(
+ $subscriber_mail, $subject, $id,
+ $template, $trep, $hrep
+ );
}
- return '/^' . $pre['user'] . '(?: ' . $pre['style'] .
- '(?: ' . $pre['data'] . ')?)?$/';
-}
-/**
- * Return a string with the email addresses of all the
- * users subscribed to a page
- *
- * This is the default action for COMMON_NOTIFY_ADDRESSLIST.
- *
- * @author Steven Danz <steven-danz@kc.rr.com>
- * @author Adrian Lang <lang@cosmocode.de>
- *
- * @todo this does NOT return a string but uses a reference to write back, either fix function or docs
- * @param array $data Containing $id (the page id), $self (whether the author
- * should be notified, $addresslist (current email address
- * list)
- * @return string
- */
-function subscription_addresslist(&$data){
- global $conf;
- /** @var auth_basic $auth */
- global $auth;
+ /**
+ * Send a notify mail on new registration
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $login login name of the new user
+ * @param string $fullname full name of the new user
+ * @param string $email email address of the new user
+ * @return bool true if a mail was sent
+ */
+ public function send_register($login, $fullname, $email) {
+ global $conf;
+ if(empty($conf['registernotify'])) return false;
- $id = $data['id'];
- $self = $data['self'];
- $addresslist = $data['addresslist'];
+ $trep = array(
+ 'NEWUSER' => $login,
+ 'NEWNAME' => $fullname,
+ 'NEWEMAIL' => $email,
+ );
- if (!$conf['subscribers'] || $auth === null) {
- return '';
+ return $this->send(
+ $conf['registernotify'],
+ 'new_user',
+ $login,
+ 'registermail',
+ $trep
+ );
}
- $pres = array('style' => 'every', 'escaped' => true);
- if (!$self && isset($_SERVER['REMOTE_USER'])) {
- $pres['user'] = '((?!' . preg_quote_cb($_SERVER['REMOTE_USER']) .
- '(?: |$))\S+)';
+
+ /**
+ * Send a digest mail
+ *
+ * Sends a digest mail showing a bunch of changes of a single page. Basically the same as send_diff()
+ * but determines the last known revision first
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ *
+ * @param string $subscriber_mail The target mail address
+ * @param array $id The ID
+ * @param int $lastupdate Time of the last notification
+ * @return bool
+ */
+ protected function send_digest($subscriber_mail, $id, $lastupdate) {
+ $n = 0;
+ do {
+ $rev = getRevisions($id, $n++, 1);
+ $rev = (count($rev) > 0) ? $rev[0] : null;
+ } while(!is_null($rev) && $rev > $lastupdate);
+
+ return $this->send_diff(
+ $subscriber_mail,
+ 'subscr_digest',
+ $id, $rev
+ );
}
- $subs = subscription_find($id, $pres);
- $emails = array();
- foreach ($subs as $by_targets) {
- foreach ($by_targets as $sub) {
- $info = $auth->getUserData($sub[0]);
- if ($info === false) continue;
- $level = auth_aclcheck($id, $sub[0], $info['grps']);
- if ($level >= AUTH_READ) {
- if (strcasecmp($info['mail'], $conf['notify']) != 0) {
- $emails[$sub[0]] = $info['mail'];
- }
- }
+
+ /**
+ * Send a list mail
+ *
+ * Sends a list mail showing a list of changed pages.
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ *
+ * @param string $subscriber_mail The target mail address
+ * @param array $ids Array of ids
+ * @param string $ns_id The id of the namespace
+ * @return bool true if a mail was sent
+ */
+ protected function send_list($subscriber_mail, $ids, $ns_id) {
+ if(count($ids) === 0) return false;
+
+ $tlist = '';
+ $hlist = '<ul>';
+ foreach($ids as $id) {
+ $link = wl($id, array(), true);
+ $tlist .= '* '.$link.NL;
+ $hlist .= '<li><a href="'.$link.'">'.hsc($id).'</a></li>'.NL;
}
+ $hlist .= '</ul>';
+
+ $id = prettyprint_id($ns_id);
+ $trep = array(
+ 'DIFF' => rtrim($tlist),
+ 'PAGE' => $id,
+ 'SUBSCRIBE' => wl($id, array('do' => 'subscribe'), true, '&')
+ );
+ $hrep = array(
+ 'DIFF' => $hlist
+ );
+
+ return $this->send(
+ $subscriber_mail,
+ 'subscribe_list',
+ $ns_id,
+ 'subscr_list', $trep, $hrep
+ );
}
- $data['addresslist'] = trim($addresslist . ',' . implode(',', $emails), ',');
-}
-/**
- * Send a digest mail
- *
- * Sends a digest mail showing a bunch of changes.
- *
- * @author Adrian Lang <lang@cosmocode.de>
- *
- * @param string $subscriber_mail The target mail address
- * @param array $id The ID
- * @param int $lastupdate Time of the last notification
- */
-function subscription_send_digest($subscriber_mail, $id, $lastupdate) {
- $n = 0;
- do {
- $rev = getRevisions($id, $n++, 1);
- $rev = (count($rev) > 0) ? $rev[0] : null;
- } while (!is_null($rev) && $rev > $lastupdate);
-
- $replaces = array('NEWPAGE' => wl($id, '', true, '&'),
- 'SUBSCRIBE' => wl($id, array('do' => 'subscribe'), true, '&'));
- if (!is_null($rev)) {
- $subject = 'changed';
- $replaces['OLDPAGE'] = wl($id, "rev=$rev", true, '&');
- $df = new Diff(explode("\n", rawWiki($id, $rev)),
- explode("\n", rawWiki($id)));
- $dformat = new UnifiedDiffFormatter();
- $replaces['DIFF'] = $dformat->format($df);
- } else {
- $subject = 'newpage';
- $replaces['OLDPAGE'] = 'none';
- $replaces['DIFF'] = rawWiki($id);
+ /**
+ * Helper function for sending a mail
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ *
+ * @param string $subscriber_mail The target mail address
+ * @param string $subject The lang id of the mail subject (without the
+ * prefix “mail_”)
+ * @param string $context The context of this mail, eg. page or namespace id
+ * @param string $template The name of the mail template
+ * @param array $trep Predefined parameters used to parse the
+ * template (in text format)
+ * @param array $hrep Predefined parameters used to parse the
+ * template (in HTML format), null to default to $trep
+ * @return bool
+ */
+ protected function send($subscriber_mail, $subject, $context, $template, $trep, $hrep = null) {
+ global $lang;
+ global $conf;
+
+ $text = rawLocale($template);
+ $subject = $lang['mail_'.$subject].' '.$context;
+ $mail = new Mailer();
+ $mail->bcc($subscriber_mail);
+ $mail->subject($subject);
+ $mail->setBody($text, $trep, $hrep);
+ if(in_array($template, array('subscr_list', 'subscr_digest'))){
+ $mail->from($conf['mailfromnobody']);
+ }
+ if(isset($trep['SUBSCRIBE'])) {
+ $mail->setHeader('List-Unsubscribe', '<'.$trep['SUBSCRIBE'].'>', false);
+ }
+ return $mail->send();
}
- subscription_send($subscriber_mail, $replaces, $subject, $id,
- 'subscr_digest');
-}
-/**
- * Send a list mail
- *
- * Sends a list mail showing a list of changed pages.
- *
- * @author Adrian Lang <lang@cosmocode.de>
- *
- * @param string $subscriber_mail The target mail address
- * @param array $ids Array of ids
- * @param string $ns_id The id of the namespace
- */
-function subscription_send_list($subscriber_mail, $ids, $ns_id) {
- if (count($ids) === 0) return;
- global $conf;
- $list = '';
- foreach ($ids as $id) {
- $list .= '* ' . wl($id, array(), true) . NL;
+ /**
+ * Default callback for COMMON_NOTIFY_ADDRESSLIST
+ *
+ * Aggregates all email addresses of user who have subscribed the given page with 'every' style
+ *
+ * @author Steven Danz <steven-danz@kc.rr.com>
+ * @author Adrian Lang <lang@cosmocode.de>
+ *
+ * @todo move the whole functionality into this class, trigger SUBSCRIPTION_NOTIFY_ADDRESSLIST instead,
+ * use an array for the addresses within it
+ *
+ * @param array &$data Containing $id (the page id), $self (whether the author
+ * should be notified, $addresslist (current email address
+ * list)
+ */
+ public function notifyaddresses(&$data) {
+ if(!$this->isenabled()) return;
+
+ /** @var auth_basic $auth */
+ global $auth;
+ global $conf;
+
+ $id = $data['id'];
+ $self = $data['self'];
+ $addresslist = $data['addresslist'];
+
+ $subscriptions = $this->subscribers($id, null, 'every');
+
+ $result = array();
+ foreach($subscriptions as $target => $users) {
+ foreach($users as $user => $info) {
+ $userinfo = $auth->getUserData($user);
+ if($userinfo === false) continue;
+ if(!$userinfo['mail']) continue;
+ if(!$self && $user == $_SERVER['REMOTE_USER']) continue; //skip our own changes
+
+ $level = auth_aclcheck($id, $user, $userinfo['grps']);
+ if($level >= AUTH_READ) {
+ if(strcasecmp($userinfo['mail'], $conf['notify']) != 0) { //skip user who get notified elsewhere
+ $result[$user] = $userinfo['mail'];
+ }
+ }
+ }
+ }
+ $data['addresslist'] = trim($addresslist.','.implode(',', $result), ',');
}
- subscription_send($subscriber_mail,
- array('DIFF' => rtrim($list),
- 'SUBSCRIBE' => wl($ns_id . $conf['start'],
- array('do' => 'subscribe'),
- true, '&')),
- 'subscribe_list',
- prettyprint_id($ns_id),
- 'subscr_list');
}
/**
- * Helper function for sending a mail
+ * Compatibility wrapper around Subscription:notifyaddresses
*
- * @author Adrian Lang <lang@cosmocode.de>
+ * for plugins emitting COMMON_NOTIFY_ADDRESSLIST themselves and relying on on this to
+ * be the default handler
*
- * @param string $subscriber_mail The target mail address
- * @param array $replaces Predefined parameters used to parse the
- * template
- * @param string $subject The lang id of the mail subject (without the
- * prefix “mail_”)
- * @param string $id The page or namespace id
- * @param string $template The name of the mail template
- * @return bool
+ * @param array $data event data for
+ *
+ * @deprecated 2012-12-07
*/
-function subscription_send($subscriber_mail, $replaces, $subject, $id, $template) {
- global $lang;
- global $conf;
-
- $text = rawLocale($template);
- $trep = array_merge($replaces, array('PAGE' => $id));
- $hrep = $trep;
- $hrep['DIFF'] = nl2br(htmlspecialchars($hrep['DIFF']));
-
- $subject = $lang['mail_' . $subject] . ' ' . $id;
- $mail = new Mailer();
- $mail->bcc($subscriber_mail);
- $mail->subject($subject);
- $mail->setBody($text,$trep,$hrep);
- $mail->from($conf['mailfromnobody']);
- $mail->setHeader(
- 'List-Unsubscribe',
- '<'.wl($id,array('do'=>'subscribe'),true,'&').'>',
- false
- );
- return $mail->send();
-}
+function subscription_addresslist(&$data) {
+ $sub = new Subscription();
+ $sub->notifyaddresses($data);
+} \ No newline at end of file