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