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