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