| 
							- <?php
 - 
 - namespace dokuwiki\Subscriptions;
 - 
 - use dokuwiki\Extension\AuthPlugin;
 - use dokuwiki\Input\Input;
 - 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
 -      * @throws Exception
 -      */
 -     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”.
 -      *
 -      * @param string $id Page ID, defaults to global $ID
 -      * @param string $user User, defaults to $_SERVER['REMOTE_USER']
 -      *
 -      * @return array|false
 -      * @throws Exception
 -      *
 -      * @author Adrian Lang <lang@cosmocode.de>
 -      */
 -     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 ($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.
 -      *
 -      * @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
 -      * @throws Exception
 -      *
 -      * @author Adrian Lang <lang@cosmocode.de>
 -      *
 -      */
 -     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;
 -                 }
 - 
 -                 // if no last sent is set, use 0
 -                 if (!isset($m[3])) {
 -                     $m[3] = 0;
 -                 }
 - 
 -                 $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
 -      *
 -      * @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)
 -      * @throws Exception
 -      *
 -      * @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
 -      */
 -     public function notifyAddresses(&$data)
 -     {
 -         if (!$this->isenabled()) {
 -             return;
 -         }
 - 
 -         /** @var AuthPlugin $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 $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 (str_ends_with($id, ':')) {
 -             $meta_froot = getNS($id);
 -             $meta_fname = '/' . $meta_fname;
 -         } else {
 -             $meta_froot = $id;
 -         }
 -         return metaFN((string)$meta_froot, $meta_fname);
 -     }
 - }
 
 
  |