ajout de la partie slam dans le dossier web
This commit is contained in:
		
							
								
								
									
										261
									
								
								ap23/web/doku/inc/Subscriptions/BulkSubscriptionSender.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										261
									
								
								ap23/web/doku/inc/Subscriptions/BulkSubscriptionSender.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,261 @@ | ||||
| <?php | ||||
|  | ||||
|  | ||||
| namespace dokuwiki\Subscriptions; | ||||
|  | ||||
|  | ||||
| use dokuwiki\ChangeLog\PageChangeLog; | ||||
| use dokuwiki\Input\Input; | ||||
| use DokuWiki_Auth_Plugin; | ||||
|  | ||||
| class BulkSubscriptionSender extends SubscriptionSender | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * 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 sendBulk($page) | ||||
|     { | ||||
|         $subscriberManager = new SubscriberManager(); | ||||
|         if (!$subscriberManager->isenabled()) { | ||||
|             return 0; | ||||
|         } | ||||
|  | ||||
|         /** @var DokuWiki_Auth_Plugin $auth */ | ||||
|         global $auth; | ||||
|         global $conf; | ||||
|         global $USERINFO; | ||||
|         /** @var Input $INPUT */ | ||||
|         global $INPUT; | ||||
|         $count = 0; | ||||
|  | ||||
|         $subscriptions = $subscriberManager->subscribers($page, null, ['digest', 'list']); | ||||
|  | ||||
|         // remember current user info | ||||
|         $olduinfo = $USERINFO; | ||||
|         $olduser = $INPUT->server->str('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); | ||||
|                 $INPUT->server->set('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 = [$meta['last_change']]; | ||||
|                 } | ||||
|  | ||||
|                 // Filter out pages only changed in small and own edits | ||||
|                 $change_ids = []; | ||||
|                 foreach ($changes as $rev) { | ||||
|                     $n = 0; | ||||
|                     while (!is_null($rev) && $rev['date'] >= $lastupdate && | ||||
|                         ($INPUT->server->str('REMOTE_USER') === $rev['user'] || | ||||
|                             $rev['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT)) { | ||||
|                         $pagelog = new PageChangeLog($rev['id']); | ||||
|                         $rev = $pagelog->getRevisions($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->sendDigest( | ||||
|                             $USERINFO['mail'], | ||||
|                             $change_id, | ||||
|                             $lastupdate | ||||
|                         ); | ||||
|                         $count++; | ||||
|                     } | ||||
|                 } else { | ||||
|                     if ($style === 'list') { | ||||
|                         $this->sendList($USERINFO['mail'], $change_ids, $target); | ||||
|                         $count++; | ||||
|                     } | ||||
|                 } | ||||
|                 // TODO: Handle duplicate subscriptions. | ||||
|  | ||||
|                 // Update notification time. | ||||
|                 $subscriberManager->add($target, $user, $style, time()); | ||||
|             } | ||||
|             $this->unlock($target); | ||||
|         } | ||||
|  | ||||
|         // restore current user info | ||||
|         $USERINFO = $olduinfo; | ||||
|         $INPUT->server->set('REMOTE_USER', $olduser); | ||||
|         return $count; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Lock subscription info | ||||
|      * | ||||
|      * We don't use io_lock() her because we do not wait for the lock and use a larger stale time | ||||
|      * | ||||
|      * @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 | ||||
|      * @author Adrian Lang <lang@cosmocode.de> | ||||
|      */ | ||||
|     protected function lock($id) | ||||
|     { | ||||
|         global $conf; | ||||
|  | ||||
|         $lock = $conf['lockdir'] . '/_subscr_' . md5($id) . '.lock'; | ||||
|  | ||||
|         if (is_dir($lock) && time() - @filemtime($lock) > 60 * 5) { | ||||
|             // looks like a stale lock - remove it | ||||
|             @rmdir($lock); | ||||
|         } | ||||
|  | ||||
|         // try creating the lock directory | ||||
|         if (!@mkdir($lock, $conf['dmode'])) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         if (!empty($conf['dperm'])) { | ||||
|             chmod($lock, $conf['dperm']); | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Unlock subscription info | ||||
|      * | ||||
|      * @param string $id The target page or namespace, specified by id; Namespaces | ||||
|      *                   are identified by appending a colon. | ||||
|      * | ||||
|      * @return bool | ||||
|      * @author Adrian Lang <lang@cosmocode.de> | ||||
|      */ | ||||
|     protected function unlock($id) | ||||
|     { | ||||
|         global $conf; | ||||
|         $lock = $conf['lockdir'] . '/_subscr_' . md5($id) . '.lock'; | ||||
|         return @rmdir($lock); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Send a digest mail | ||||
|      * | ||||
|      * Sends a digest mail showing a bunch of changes of a single page. Basically the same as sendPageDiff() | ||||
|      * but determines the last known revision first | ||||
|      * | ||||
|      * @param string $subscriber_mail The target mail address | ||||
|      * @param string $id              The ID | ||||
|      * @param int    $lastupdate      Time of the last notification | ||||
|      * | ||||
|      * @return bool | ||||
|      * @author Adrian Lang <lang@cosmocode.de> | ||||
|      * | ||||
|      */ | ||||
|     protected function sendDigest($subscriber_mail, $id, $lastupdate) | ||||
|     { | ||||
|         $pagelog = new PageChangeLog($id); | ||||
|         $n = 0; | ||||
|         do { | ||||
|             $rev = $pagelog->getRevisions($n++, 1); | ||||
|             $rev = (count($rev) > 0) ? $rev[0] : null; | ||||
|         } while (!is_null($rev) && $rev > $lastupdate); | ||||
|  | ||||
|         // TODO I'm not happy with the following line and passing $this->mailer around. Not sure how to solve it better | ||||
|         $pageSubSender = new PageSubscriptionSender($this->mailer); | ||||
|         return $pageSubSender->sendPageDiff( | ||||
|             $subscriber_mail, | ||||
|             'subscr_digest', | ||||
|             $id, | ||||
|             $rev | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Send a list mail | ||||
|      * | ||||
|      * Sends a list mail showing a list of changed pages. | ||||
|      * | ||||
|      * @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 | ||||
|      * @author Adrian Lang <lang@cosmocode.de> | ||||
|      * | ||||
|      */ | ||||
|     protected function sendList($subscriber_mail, $ids, $ns_id) | ||||
|     { | ||||
|         if (count($ids) === 0) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         $tlist = ''; | ||||
|         $hlist = '<ul>'; | ||||
|         foreach ($ids as $id) { | ||||
|             $link = wl($id, [], true); | ||||
|             $tlist .= '* ' . $link . NL; | ||||
|             $hlist .= '<li><a href="' . $link . '">' . hsc($id) . '</a></li>' . NL; | ||||
|         } | ||||
|         $hlist .= '</ul>'; | ||||
|  | ||||
|         $id = prettyprint_id($ns_id); | ||||
|         $trep = [ | ||||
|             'DIFF' => rtrim($tlist), | ||||
|             'PAGE' => $id, | ||||
|             'SUBSCRIBE' => wl($id, ['do' => 'subscribe'], true, '&'), | ||||
|         ]; | ||||
|         $hrep = [ | ||||
|             'DIFF' => $hlist, | ||||
|         ]; | ||||
|  | ||||
|         return $this->send( | ||||
|             $subscriber_mail, | ||||
|             'subscribe_list', | ||||
|             $ns_id, | ||||
|             'subscr_list', | ||||
|             $trep, | ||||
|             $hrep | ||||
|         ); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										47
									
								
								ap23/web/doku/inc/Subscriptions/MediaSubscriptionSender.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								ap23/web/doku/inc/Subscriptions/MediaSubscriptionSender.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | ||||
| <?php | ||||
|  | ||||
|  | ||||
| namespace dokuwiki\Subscriptions; | ||||
|  | ||||
|  | ||||
| class MediaSubscriptionSender extends SubscriptionSender | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * Send the diff for some media change | ||||
|      * | ||||
|      * @fixme this should embed thumbnails of images in HTML version | ||||
|      * | ||||
|      * @param string   $subscriber_mail The target mail address | ||||
|      * @param string   $template        Mail template ('uploadmail', ...) | ||||
|      * @param string   $id              Media file for which the notification is | ||||
|      * @param int|bool $rev             Old revision if any | ||||
|      * @param int|bool $current_rev     New revision if any | ||||
|      */ | ||||
|     public function sendMediaDiff($subscriber_mail, $template, $id, $rev = false, $current_rev = false) | ||||
|     { | ||||
|         global $conf; | ||||
|  | ||||
|         $file = mediaFN($id); | ||||
|         list($mime, /* $ext */) = mimetype($id); | ||||
|  | ||||
|         $trep = [ | ||||
|             'MIME' => $mime, | ||||
|             'MEDIA' => ml($id, $current_rev?('rev='.$current_rev):'', true, '&', true), | ||||
|             'SIZE' => filesize_h(filesize($file)), | ||||
|         ]; | ||||
|  | ||||
|         if ($rev && $conf['mediarevisions']) { | ||||
|             $trep['OLD'] = ml($id, "rev=$rev", true, '&', true); | ||||
|         } else { | ||||
|             $trep['OLD'] = '---'; | ||||
|         } | ||||
|  | ||||
|         $headers = ['Message-Id' => $this->getMessageID($id, @filemtime($file))]; | ||||
|         if ($rev) { | ||||
|             $headers['In-Reply-To'] = $this->getMessageID($id, $rev); | ||||
|         } | ||||
|  | ||||
|         $this->send($subscriber_mail, 'upload', $id, $template, $trep, null, $headers); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										88
									
								
								ap23/web/doku/inc/Subscriptions/PageSubscriptionSender.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								ap23/web/doku/inc/Subscriptions/PageSubscriptionSender.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | ||||
| <?php | ||||
|  | ||||
|  | ||||
| namespace dokuwiki\Subscriptions; | ||||
|  | ||||
|  | ||||
| use Diff; | ||||
| use InlineDiffFormatter; | ||||
| use UnifiedDiffFormatter; | ||||
|  | ||||
| class PageSubscriptionSender extends SubscriptionSender | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * 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 | ||||
|      * @param int|null $current_rev     New revision if any | ||||
|      * | ||||
|      * @return bool                     true if successfully sent | ||||
|      */ | ||||
|     public function sendPageDiff($subscriber_mail, $template, $id, $rev = null, $summary = '', $current_rev = null) | ||||
|     { | ||||
|         global $DIFF_INLINESTYLES; | ||||
|  | ||||
|         // prepare replacements (keys not set in hrep will be taken from trep) | ||||
|         $trep = [ | ||||
|             'PAGE' => $id, | ||||
|             'NEWPAGE' => wl($id, $current_rev?('rev='.$current_rev):'', true, '&'), | ||||
|             'SUMMARY' => $summary, | ||||
|             'SUBSCRIBE' => wl($id, ['do' => 'subscribe'], true, '&'), | ||||
|         ]; | ||||
|         $hrep = []; | ||||
|  | ||||
|         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", $old_content), | ||||
|                 explode("\n", $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; | ||||
|  | ||||
|         $headers = ['Message-Id' => $this->getMessageID($id)]; | ||||
|         if ($rev) { | ||||
|             $headers['In-Reply-To'] = $this->getMessageID($id, $rev); | ||||
|         } | ||||
|  | ||||
|         return $this->send( | ||||
|             $subscriber_mail, | ||||
|             $subject, | ||||
|             $id, | ||||
|             $template, | ||||
|             $trep, | ||||
|             $hrep, | ||||
|             $headers | ||||
|         ); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,40 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Subscriptions; | ||||
|  | ||||
| class RegistrationSubscriptionSender extends SubscriptionSender | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * Send a notify mail on new registration | ||||
|      * | ||||
|      * @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 | ||||
|      * @author Andreas Gohr <andi@splitbrain.org> | ||||
|      * | ||||
|      */ | ||||
|     public function sendRegister($login, $fullname, $email) | ||||
|     { | ||||
|         global $conf; | ||||
|         if (empty($conf['registernotify'])) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         $trep = [ | ||||
|             'NEWUSER' => $login, | ||||
|             'NEWNAME' => $fullname, | ||||
|             'NEWEMAIL' => $email, | ||||
|         ]; | ||||
|  | ||||
|         return $this->send( | ||||
|             $conf['registernotify'], | ||||
|             'new_user', | ||||
|             $login, | ||||
|             'registermail', | ||||
|             $trep | ||||
|         ); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										290
									
								
								ap23/web/doku/inc/Subscriptions/SubscriberManager.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										290
									
								
								ap23/web/doku/inc/Subscriptions/SubscriberManager.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,290 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Subscriptions; | ||||
|  | ||||
| use dokuwiki\Input\Input; | ||||
| use DokuWiki_Auth_Plugin; | ||||
| use Exception; | ||||
|  | ||||
| class SubscriberManager | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * Check if subscription system is enabled | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function isenabled() | ||||
|     { | ||||
|         return actionOK('subscribe'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 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. | ||||
|      * | ||||
|      * @throws Exception when user or style is empty | ||||
|      * | ||||
|      * @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 | ||||
|      * | ||||
|      * @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); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 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; | ||||
|         } | ||||
|  | ||||
|         $regexBuilder = new SubscriberRegexBuilder(); | ||||
|         $re = $regexBuilder->buildRegex($user, $style, $data); | ||||
|         return io_deleteFromFile($file, $re, true); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 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> | ||||
|      * | ||||
|      * @param string $id   Page ID, defaults to global $ID | ||||
|      * @param string $user User, defaults to $_SERVER['REMOTE_USER'] | ||||
|      * | ||||
|      * @return array|false | ||||
|      */ | ||||
|     public function userSubscription($id = '', $user = '') | ||||
|     { | ||||
|         if (!$this->isenabled()) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         global $ID; | ||||
|         /** @var Input $INPUT */ | ||||
|         global $INPUT; | ||||
|         if (!$id) { | ||||
|             $id = $ID; | ||||
|         } | ||||
|         if (!$user) { | ||||
|             $user = $INPUT->server->str('REMOTE_USER'); | ||||
|         } | ||||
|  | ||||
|         if (empty($user)) { | ||||
|             // not logged in | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         $subs = $this->subscribers($id, $user); | ||||
|         if (!count($subs)) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         $result = []; | ||||
|         foreach ($subs as $target => $info) { | ||||
|             $result[] = [ | ||||
|                 'target' => $target, | ||||
|                 'style' => $info[$user][0], | ||||
|                 'data' => $info[$user][1], | ||||
|             ]; | ||||
|         } | ||||
|  | ||||
|         return $result; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 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 []; | ||||
|         } | ||||
|  | ||||
|         // Construct list of files which may contain relevant subscriptions. | ||||
|         $files = [':' => $this->file(':')]; | ||||
|         do { | ||||
|             $files[$page] = $this->file($page); | ||||
|             $page = getNS(rtrim($page, ':')) . ':'; | ||||
|         } while ($page !== ':'); | ||||
|  | ||||
|         $regexBuilder = new SubscriberRegexBuilder(); | ||||
|         $re = $regexBuilder->buildRegex($user, $style, $data); | ||||
|  | ||||
|         // Handle files. | ||||
|         $result = []; | ||||
|         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] = []; | ||||
|                 } | ||||
|                 $result[$target][$u] = [$m[2], $m[3]]; // add to result | ||||
|             } | ||||
|         } | ||||
|         return array_reverse($result); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Default callback for COMMON_NOTIFY_ADDRESSLIST | ||||
|      * | ||||
|      * Aggregates all email addresses of user who have subscribed the given page with 'every' style | ||||
|      * | ||||
|      * @author Adrian Lang <lang@cosmocode.de> | ||||
|      * @author Steven Danz <steven-danz@kc.rr.com> | ||||
|      * | ||||
|      * @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 the entries: | ||||
|      *                     - $id (the page id), | ||||
|      *                     - $self (whether the author should be notified, | ||||
|      *                     - $addresslist (current email address list) | ||||
|      *                     - $replacements (array of additional string substitutions, @KEY@ to be replaced by value) | ||||
|      */ | ||||
|     public function notifyAddresses(&$data) | ||||
|     { | ||||
|         if (!$this->isenabled()) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         /** @var DokuWiki_Auth_Plugin $auth */ | ||||
|         global $auth; | ||||
|         global $conf; | ||||
|         /** @var \Input $INPUT */ | ||||
|         global $INPUT; | ||||
|  | ||||
|         $id = $data['id']; | ||||
|         $self = $data['self']; | ||||
|         $addresslist = $data['addresslist']; | ||||
|  | ||||
|         $subscriptions = $this->subscribers($id, null, 'every'); | ||||
|  | ||||
|         $result = []; | ||||
|         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 == $INPUT->server->str('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), ','); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 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); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										70
									
								
								ap23/web/doku/inc/Subscriptions/SubscriberRegexBuilder.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								ap23/web/doku/inc/Subscriptions/SubscriberRegexBuilder.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Subscriptions; | ||||
|  | ||||
| use Exception; | ||||
|  | ||||
| class SubscriberRegexBuilder | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * Construct a regular expression for parsing a subscription definition line | ||||
|      * | ||||
|      * @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 | ||||
|      * @author Andreas Gohr <andi@splitbrain.org> | ||||
|      * | ||||
|      */ | ||||
|     public 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+'; | ||||
|         } | ||||
|         if ($style === '') { | ||||
|             $style = '\S+'; | ||||
|             $sopt = '?'; | ||||
|         } | ||||
|         if ($data === '') { | ||||
|             $data = '\S+'; | ||||
|             $dopt = '?'; | ||||
|         } | ||||
|  | ||||
|         // assemble | ||||
|         return "/^($user)(?:\\s+($style))$sopt(?:\\s+($data))$dopt$/"; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										86
									
								
								ap23/web/doku/inc/Subscriptions/SubscriptionSender.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								ap23/web/doku/inc/Subscriptions/SubscriptionSender.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Subscriptions; | ||||
|  | ||||
| use Mailer; | ||||
|  | ||||
| abstract class SubscriptionSender | ||||
| { | ||||
|     protected $mailer; | ||||
|  | ||||
|     public function __construct(Mailer $mailer = null) | ||||
|     { | ||||
|         if ($mailer === null) { | ||||
|             $mailer = new Mailer(); | ||||
|         } | ||||
|         $this->mailer = $mailer; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get a valid message id for a certain $id and revision (or the current revision) | ||||
|      * | ||||
|      * @param string $id  The id of the page (or media file) the message id should be for | ||||
|      * @param string $rev The revision of the page, set to the current revision of the page $id if not set | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     protected function getMessageID($id, $rev = null) | ||||
|     { | ||||
|         static $listid = null; | ||||
|         if (is_null($listid)) { | ||||
|             $server = parse_url(DOKU_URL, PHP_URL_HOST); | ||||
|             $listid = join('.', array_reverse(explode('/', DOKU_BASE))) . $server; | ||||
|             $listid = urlencode($listid); | ||||
|             $listid = strtolower(trim($listid, '.')); | ||||
|         } | ||||
|  | ||||
|         if (is_null($rev)) { | ||||
|             $rev = @filemtime(wikiFN($id)); | ||||
|         } | ||||
|  | ||||
|         return "<$id?rev=$rev@$listid>"; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Helper function for sending a mail | ||||
|      * | ||||
|      * @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 | ||||
|      * @param array  $headers         Additional mail headers in the form 'name' => 'value' | ||||
|      * | ||||
|      * @return bool | ||||
|      * @author Adrian Lang <lang@cosmocode.de> | ||||
|      * | ||||
|      */ | ||||
|     protected function send($subscriber_mail, $subject, $context, $template, $trep, $hrep = null, $headers = []) | ||||
|     { | ||||
|         global $lang; | ||||
|         global $conf; | ||||
|  | ||||
|         $text = rawLocale($template); | ||||
|         $subject = $lang['mail_' . $subject] . ' ' . $context; | ||||
|         $mail = $this->mailer; | ||||
|         $mail->bcc($subscriber_mail); | ||||
|         $mail->subject($subject); | ||||
|         $mail->setBody($text, $trep, $hrep); | ||||
|         if (in_array($template, ['subscr_list', 'subscr_digest'])) { | ||||
|             $mail->from($conf['mailfromnobody']); | ||||
|         } | ||||
|         if (isset($trep['SUBSCRIBE'])) { | ||||
|             $mail->setHeader('List-Unsubscribe', '<' . $trep['SUBSCRIBE'] . '>', false); | ||||
|         } | ||||
|  | ||||
|         foreach ($headers as $header => $value) { | ||||
|             $mail->setHeader($header, $value); | ||||
|         } | ||||
|  | ||||
|         return $mail->send(); | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user