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