diff options
author | Andreas Gohr <andi@splitbrain.org> | 2012-08-12 15:07:03 +0200 |
---|---|---|
committer | Andreas Gohr <andi@splitbrain.org> | 2012-08-12 15:07:03 +0200 |
commit | adec979fd5453cf213b776d7dceaaaac4eb05713 (patch) | |
tree | e473c5a2e9627d36605bea573efa0933c55f3f47 /inc/subscription.php | |
parent | e920a0a10c3027700e61166a6f8d4ea29a9ff102 (diff) | |
download | rpg-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/subscription.php')
-rw-r--r-- | inc/subscription.php | 191 |
1 files changed, 146 insertions, 45 deletions
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 |