summaryrefslogtreecommitdiff
path: root/inc
diff options
context:
space:
mode:
authorAndreas Gohr <andi@splitbrain.org>2012-08-12 15:07:03 +0200
committerAndreas Gohr <andi@splitbrain.org>2012-08-12 15:07:03 +0200
commitadec979fd5453cf213b776d7dceaaaac4eb05713 (patch)
treee473c5a2e9627d36605bea573efa0933c55f3f47 /inc
parente920a0a10c3027700e61166a6f8d4ea29a9ff102 (diff)
downloadrpg-adec979fd5453cf213b776d7dceaaaac4eb05713.tar.gz
rpg-adec979fd5453cf213b776d7dceaaaac4eb05713.tar.bz2
more subscription refactoring BROKEN
now the actual sending of bulk messages (digest, list) is reimplemented and partially tested. Still not complete
Diffstat (limited to 'inc')
-rw-r--r--inc/common.php4
-rw-r--r--inc/subscription.php191
2 files changed, 149 insertions, 46 deletions
diff --git a/inc/common.php b/inc/common.php
index ac7e744d8..29940d8a6 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) {
diff --git a/inc/subscription.php b/inc/subscription.php
index 856836cd5..804776ced 100644
--- a/inc/subscription.php
+++ b/inc/subscription.php
@@ -253,24 +253,23 @@ class Subscription {
* @return array
* @author Adrian Lang <lang@cosmocode.de>
*/
- function user_subscription($id='', $user='') {
+ function user_subscription($id = '', $user = '') {
global $ID;
global $conf;
if(!$conf['subscribers']) return false;
- if(!$id) $id = $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 => $data) {
+ foreach($subs as $target => $info) {
$result[] = array(
'target' => $target,
- 'style' => $data[$user][0],
- 'data' => $data[$user][1]
+ 'style' => $info[$user][0],
+ 'data' => $info[$user][1]
);
}
@@ -278,52 +277,100 @@ class Subscription {
}
/**
- * Return a string with the email addresses of all the
- * users subscribed to a page
+ * Send digest and list subscriptions
*
- * This is the default action for COMMON_NOTIFY_ADDRESSLIST.
+ * 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.
*
- * @author Steven Danz <steven-danz@kc.rr.com>
- * @author Adrian Lang <lang@cosmocode.de>
+ * This function is called form lib/exe/indexer.php
*
- * @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
+ * @param string $page
+ * @return int number of sent mails
*/
- function subscription_addresslist(&$data) {
- global $conf;
+ public function send_bulk($page) {
/** @var auth_basic $auth */
global $auth;
+ global $conf;
+ global $USERINFO;
+ $count = 0;
- $id = $data['id'];
- $self = $data['self'];
- $addresslist = $data['addresslist'];
+ $subscriptions = $this->subscribers($page, null, array('digest', 'list'));
- if(!$conf['subscribers'] || $auth === null) {
- return '';
- }
- $pres = array('style' => 'every', 'escaped' => true);
- if(!$self && isset($_SERVER['REMOTE_USER'])) {
- $pres['user'] = '((?!'.preg_quote_cb($_SERVER['REMOTE_USER']).
- '(?: |$))\S+)';
- }
- $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'];
+ // 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);
}
- $data['addresslist'] = trim($addresslist.','.implode(',', $emails), ',');
+
+ // restore current user info
+ $USERINFO = $olduinfo;
+ $_SERVER['REMOTE_USER'] = $olduser;
+ return $count;
}
/**
@@ -337,7 +384,7 @@ class Subscription {
* @param array $id The ID
* @param int $lastupdate Time of the last notification
*/
- function subscription_send_digest($subscriber_mail, $id, $lastupdate) {
+ protected function send_digest($subscriber_mail, $id, $lastupdate) {
$n = 0;
do {
$rev = getRevisions($id, $n++, 1);
@@ -360,7 +407,7 @@ class Subscription {
$replaces['OLDPAGE'] = 'none';
$replaces['DIFF'] = rawWiki($id);
}
- subscription_send(
+ $this->send(
$subscriber_mail, $replaces, $subject, $id,
'subscr_digest'
);
@@ -377,14 +424,14 @@ class Subscription {
* @param array $ids Array of ids
* @param string $ns_id The id of the namespace
*/
- function subscription_send_list($subscriber_mail, $ids, $ns_id) {
+ protected function 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;
}
- subscription_send(
+ $this->send(
$subscriber_mail,
array(
'DIFF' => rtrim($list),
@@ -414,7 +461,7 @@ class Subscription {
* @param string $template The name of the mail template
* @return bool
*/
- function subscription_send($subscriber_mail, $replaces, $subject, $id, $template) {
+ protected function send($subscriber_mail, $replaces, $subject, $id, $template) {
global $lang;
$text = rawLocale($template);
@@ -433,4 +480,58 @@ class Subscription {
return $mail->send();
}
+
+
+ // FIXME no refactoring below, yet
+
+ /**
+ * 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;
+
+ $id = $data['id'];
+ $self = $data['self'];
+ $addresslist = $data['addresslist'];
+
+ if(!$conf['subscribers'] || $auth === null) {
+ return '';
+ }
+ $pres = array('style' => 'every', 'escaped' => true);
+ if(!$self && isset($_SERVER['REMOTE_USER'])) {
+ $pres['user'] = '((?!'.preg_quote_cb($_SERVER['REMOTE_USER']).
+ '(?: |$))\S+)';
+ }
+ $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'];
+ }
+ }
+ }
+ }
+ $data['addresslist'] = trim($addresslist.','.implode(',', $emails), ',');
+ }
+
+
} \ No newline at end of file