xref: /dokuwiki/inc/Action/Subscribe.php (revision 704a815fe827ce918bab0973cde563705c65c698)
1<?php
2
3namespace dokuwiki\Action;
4
5use dokuwiki\Action\Exception\ActionAbort;
6use dokuwiki\Action\Exception\ActionDisabledException;
7use dokuwiki\Subscriptions\SubscriberManager;
8
9/**
10 * Class Subscribe
11 *
12 * E-Mail subscription handling
13 *
14 * @package dokuwiki\Action
15 */
16class Subscribe extends AbstractUserAction {
17
18    /** @inheritdoc */
19    public function minimumPermission() {
20        return AUTH_READ;
21    }
22
23    /** @inheritdoc */
24    public function checkPreconditions() {
25        parent::checkPreconditions();
26
27        global $conf;
28        if(isset($conf['subscribers']) && !$conf['subscribers']) throw new ActionDisabledException();
29    }
30
31    /** @inheritdoc */
32    public function preProcess() {
33        try {
34            $this->handleSubscribeData();
35        } catch(ActionAbort $e) {
36            throw $e;
37        } catch(\Exception $e) {
38            msg($e->getMessage(), -1);
39        }
40    }
41
42    /** @inheritdoc */
43    public function tplContent() {
44        tpl_subscribe();
45    }
46
47    /**
48     * Handle page 'subscribe'
49     *
50     * @author Adrian Lang <lang@cosmocode.de>
51     * @throws \Exception if (un)subscribing fails
52     * @throws ActionAbort when (un)subscribing worked
53     */
54    protected function handleSubscribeData() {
55        global $lang;
56        global $INFO;
57        global $INPUT;
58
59        // get and preprocess data.
60        $params = array();
61        foreach(array('target', 'style', 'action') as $param) {
62            if($INPUT->has("sub_$param")) {
63                $params[$param] = $INPUT->str("sub_$param");
64            }
65        }
66
67        // any action given? if not just return and show the subscription page
68        if(empty($params['action']) || !checkSecurityToken()) return;
69
70        // Handle POST data, may throw exception.
71        trigger_event('ACTION_HANDLE_SUBSCRIBE', $params, array($this, 'handlePostData'));
72
73        $target = $params['target'];
74        $style = $params['style'];
75        $action = $params['action'];
76
77        // Perform action.
78        $subManager = new SubscriberManager();
79        if($action == 'unsubscribe') {
80            $ok = $subManager->remove($target, $INPUT->server->str('REMOTE_USER'), $style);
81        } else {
82            $ok = $subManager->add($target, $INPUT->server->str('REMOTE_USER'), $style);
83        }
84
85        if($ok) {
86            msg(
87                sprintf(
88                    $lang["subscr_{$action}_success"], hsc($INFO['userinfo']['name']),
89                    prettyprint_id($target)
90                ), 1
91            );
92            throw new ActionAbort('redirect');
93        } else {
94            throw new \Exception(
95                sprintf(
96                    $lang["subscr_{$action}_error"],
97                    hsc($INFO['userinfo']['name']),
98                    prettyprint_id($target)
99                )
100            );
101        }
102    }
103
104    /**
105     * Validate POST data
106     *
107     * Validates POST data for a subscribe or unsubscribe request. This is the
108     * default action for the event ACTION_HANDLE_SUBSCRIBE.
109     *
110     * @author Adrian Lang <lang@cosmocode.de>
111     *
112     * @param array &$params the parameters: target, style and action
113     * @throws \Exception
114     */
115    public function handlePostData(&$params) {
116        global $INFO;
117        global $lang;
118        global $INPUT;
119
120        // Get and validate parameters.
121        if(!isset($params['target'])) {
122            throw new \Exception('no subscription target given');
123        }
124        $target = $params['target'];
125        $valid_styles = array('every', 'digest');
126        if(substr($target, -1, 1) === ':') {
127            // Allow “list” subscribe style since the target is a namespace.
128            $valid_styles[] = 'list';
129        }
130        $style = valid_input_set(
131            'style', $valid_styles, $params,
132            'invalid subscription style given'
133        );
134        $action = valid_input_set(
135            'action', array('subscribe', 'unsubscribe'),
136            $params, 'invalid subscription action given'
137        );
138
139        // Check other conditions.
140        if($action === 'subscribe') {
141            if($INFO['userinfo']['mail'] === '') {
142                throw new \Exception($lang['subscr_subscribe_noaddress']);
143            }
144        } elseif($action === 'unsubscribe') {
145            $is = false;
146            foreach($INFO['subscribed'] as $subscr) {
147                if($subscr['target'] === $target) {
148                    $is = true;
149                }
150            }
151            if($is === false) {
152                throw new \Exception(
153                    sprintf(
154                        $lang['subscr_not_subscribed'],
155                        $INPUT->server->str('REMOTE_USER'),
156                        prettyprint_id($target)
157                    )
158                );
159            }
160            // subscription_set deletes a subscription if style = null.
161            $style = null;
162        }
163
164        $params = compact('target', 'style', 'action');
165    }
166
167}
168