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