1<?php 2 3class action_plugin_infomail extends DokuWiki_Action_Plugin 4{ 5 /** @inheritdoc */ 6 public function register(Doku_Event_Handler $controller) 7 { 8 // we handle AJAX and non AJAX requesat through the same handler 9 $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handleEvent'); 10 $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleEvent'); 11 $controller->register_hook('TPL_ACT_UNKNOWN', 'BEFORE', $this, 'handleEvent'); 12 } 13 14 /** 15 * @param Doku_Event $event 16 */ 17 public function handleEvent(Doku_Event $event) 18 { 19 // the basic handling is the same for all events 20 // we either show the form or handle the post data 21 22 // FIXME change this into one string 23 if (!in_array($event->data, array('infomail', 'plugin_infomail'))) { 24 return; 25 } 26 $event->preventDefault(); 27 // for this event we only signal, that we will handle this mode 28 if ($event->name === 'ACTION_ACT_PREPROCESS') { 29 return; 30 } 31 $event->stopPropagation(); 32 33 global $INPUT; 34 35 // early output to trigger display msgs even via AJAX. 36 echo ' '; 37 tpl_flush(); 38 if ($INPUT->server->str('REQUEST_METHOD') === 'POST') { 39 try { 40 $this->sendMail(); 41 if ($event->name === 'AJAX_CALL_UNKNOWN') { 42 $this->ajaxSuccess(); // To signal success to AJAX. 43 } else { 44 msg($this->getLang('thanks'), 1); 45 } 46 return; // we're done here 47 } catch (\Exception $e) { 48 msg($e->getMessage(), -1); 49 } 50 } 51 52 echo $this->getForm(); 53 } 54 55 /** 56 * Builds the Mail Form 57 */ 58 protected function getForm() 59 { 60 global $INPUT; 61 62 /** @var helper_plugin_infomail $helper */ 63 $helper = plugin_load('helper', 'infomail'); 64 65 $id = getID(); // we may run in AJAX context 66 if ($id === '') throw new \RuntimeException('No ID given'); 67 68 $form = new \dokuwiki\Form\Form([ 69 'action' => wl($id, ['do' => 'infomail'], false, '&'), 70 'id' => 'infomail__plugin', 71 ]); 72 $form->setHiddenField('id', $id); // we need it for the ajax call 73 74 if ($INPUT->server->has('REMOTE_USER')) { 75 global $USERINFO; 76 $form->setHiddenField('s_name', $USERINFO['name']); 77 $form->setHiddenField('s_email', $USERINFO['mail']); 78 } else { 79 $form->addTextInput('s_name', $this->getLang('yourname'))->addClass('edit'); 80 $form->addTextInput('s_email', $this->getLang('youremailaddress'))->addClass('edit'); 81 } 82 83 //get default emails from config 84 $lists = explode('|', $this->getConf('default_recipient')); 85 $lists = array_filter($lists, 'mail_isvalid'); 86 // get simple listfiles from pages and add them 87 $lists = array_merge($lists, $helper->getLists()); 88 89 if ($lists) { 90 array_unshift($lists, ''); // add empty option 91 $form->addDropdown('r_predef', $lists, $this->getLang('bookmarks')); 92 } 93 94 $form->addTextInput('r_email', $this->getLang('recipients'))->addClass('edit'); 95 $form->addTextInput('subject', $this->getLang('subject'))->addClass('edit'); 96 $form->addTextarea('comment', $this->getLang('message'))->attr('rows', '8')->attr('cols', '10')->addClass('edit'); 97 98 /** @var helper_plugin_captcha $captcha */ 99 $captcha = plugin_load('helper', 'captcha'); 100 if ($captcha) $form->addHTML($captcha->getHTML()); 101 102 //$form->addCheckbox('archiveopt', $this->getLang('archive'))->addClass('edit'); 103 104 $form->addTagOpen('div')->addClass('buttons'); 105 $form->addButton('submit', $this->getLang('send_infomail'))->attr('type', 'submit'); 106 $form->addButton('reset', $this->getLang('cancel_infomail'))->attr('type', 'reset'); 107 $form->addTagClose('div'); 108 109 return $form->toHTML(); 110 } 111 112 /** 113 * Validate input and send mail if everything is ok 114 * 115 * @throws Exception when something went wrong 116 * @todo this method is still much too long 117 */ 118 protected function sendMail() 119 { 120 global $conf; 121 global $INPUT; 122 123 /** @var helper_plugin_captcha $captcha */ 124 $captcha = plugin_load('helper', 'captcha'); 125 if ($captcha && !$captcha->check()) { 126 throw new \Exception('Wrong Captcha'); 127 } 128 129 if (!checkSecurityToken()) { 130 throw new \Exception('Security token did not match'); 131 } 132 133 /** @var helper_plugin_infomail $helper */ 134 $helper = plugin_load('helper', 'infomail'); 135 136 // Get recipients 137 $all_recipients = explode(' ', $INPUT->str('r_email')); 138 $bookmark = $INPUT->filter('trim')->str('r_predef'); 139 if ($bookmark) { 140 // a bookmark may be a single address or a list 141 if (mail_isvalid($bookmark)) { 142 $all_recipients[] = $bookmark; 143 } else { 144 $all_recipients = array_merge($all_recipients, $helper->loadList($bookmark)); 145 } 146 } 147 // clean up recipients 148 $all_recipients = array_map('trim', $all_recipients); 149 $all_recipients = array_map('strtolower', $all_recipients); 150 $all_recipients = array_filter($all_recipients, 'mail_isvalid'); 151 $all_recipients = array_unique($all_recipients); 152 if (!$all_recipients) throw new \Exception($this->getLang('novalid_rec')); 153 154 // Sender name 155 $s_name = $INPUT->filter('trim')->str('s_name', $this->getConf('default_sender_displayname')); 156 if ($s_name === '') throw new \Exception($this->getLang('err_sendername')); 157 158 // Sender email 159 $s_email = $INPUT->filter('trim')->str('s_email', $this->getConf('default_sender'), true); 160 if (!mail_isvalid($s_email)) throw new \Exception($this->getLang('err_sendermail')); 161 162 // named Sender 163 $sender = "$s_name <$s_email>"; 164 165 // the page ID 166 $id = $INPUT->filter('cleanID')->str('id'); 167 if ($id === '' || !page_exists($id)) throw new \Exception($this->getLang('err_page')); 168 169 // comment 170 $comment = $INPUT->str('comment'); 171 172 // shorturl hook 173 /** @var helper_plugin_shorturl $shorturl */ 174 $shorturl = plugin_load('helper', 'shorturl'); 175 if ($shorturl) { 176 $shortID = $shorturl->autoGenerateShortUrl($id); 177 $pageurl = wl($shortID, '', true, '&'); 178 } else { 179 $pageurl = wl($id, '', true, '&'); 180 } 181 182 // subject 183 $subject = $this->getConf('subjectprefix') . ' ' . $INPUT->str('subject'); 184 185 // prepare replacements 186 $data = [ 187 'NAME' => $INPUT->str('r_name'), 188 'PAGE' => $id, 189 'SITE' => $conf['title'], 190 'SUBJECT' => $subject, 191 'URL' => $pageurl, 192 'COMMENT' => $comment, 193 'AUTHOR' => $s_name, 194 ]; 195 196 // get the text 197 $mailtext = $helper->loadTemplate(); 198 199 // Send mail 200 $mailer = new Mailer(); 201 $mailer->bcc($all_recipients); 202 $mailer->from($sender); 203 $mailer->subject($subject); 204 $mailer->setBody($mailtext, $data); 205 $mailer->send(); 206 207 /* FIXME currently not implemented 208 if ($this->getConf('logmails')) { 209 $this->mail_log($recipient, $subject, $mailtext, $sender); 210 } 211 212 if ($archiveon) { 213 $this->mail_archive($all_recipients, $subject, $mailtext, $sender); 214 } 215 */ 216 } 217 218 /** 219 * show success message in ajax mode 220 */ 221 protected function ajaxSuccess() 222 { 223 echo '<form id="infomail_plugin" accept-charset="utf-8" method="post" action="?do=infomail">'; 224 echo '<div class="no">'; 225 echo '<span class="ui-icon ui-icon-circle-check" style="float: left; margin: 0 7px 50px 0;"></span>'; 226 echo '<p>' . $this->getLang('thanks') . '</p>'; 227 echo '<button type="reset" class="button">' . $this->getLang('close') . '</button>'; 228 echo '</div>'; 229 echo '</form>'; 230 } 231 232 /* 233 * Logging infomails as Wikipages when configured so 234 * 235 * @todo currently not used, needs adjustment 236 */ 237 protected function mail_archive($recipient, $subject, $mailtext, $sender) 238 { 239 global $conf; 240 $targetdir = $conf['cachedir'] . "/infomail-plugin/archive/"; 241 if (!is_dir($targetdir)) { 242 mkdir($targetdir); 243 } 244 245 $t = time(); 246 $date = strftime("%d.%m.%Y, %H:%M", $t); 247 $mailtext = "Von: $sender\nAn: $recipient\nDatum: $date\n\n" . $mailtext; 248 249 $filename = strftime("%Y%m%d%H%M%S", $t) . "_infomail.txt"; 250 $archfile = $targetdir . $filename; 251 io_saveFile($archfile, "$mailtext\n", true); 252 253 } 254 255 /* 256 * Logging infomails as Wikipages when configured so 257 * 258 * @todo currently not used, needs adjustment 259 */ 260 protected function mail_log($recipient, $subject, $mailtext, $sender) 261 { 262 global $conf; 263 $targetdir = $conf['cachedir'] . "/infomail-plugin/log/"; 264 $logfile = $targetdir . "infomail.log"; 265 if (!is_dir($targetdir)) { 266 mkdir($targetdir); 267 } 268 269 $t = time(); 270 $log = $t . "\t" . strftime($conf['dformat'], $t) . "\t" . $_SERVER['REMOTE_ADDR'] . "\t" . $sender . "\t" . $recipient; 271 io_saveFile($logfile, "$log\n", true); 272 273 } 274 275} 276