1<?php 2 3class action_plugin_recommend extends DokuWiki_Action_Plugin { 4 5 public function register(Doku_Event_Handler $controller) { 6 foreach (array('ACTION_ACT_PREPROCESS', 'AJAX_CALL_UNKNOWN', 7 'TPL_ACT_UNKNOWN') as $event) { 8 $controller->register_hook($event, 'BEFORE', $this, 'handle'); 9 } 10 $controller->register_hook('MENU_ITEMS_ASSEMBLY', 'AFTER', $this, 'handleMenu'); 11 } 12 13 public function handle(Doku_Event $event) { 14 if ($event->data !=='recommend') { 15 return; 16 } 17 18 $event->preventDefault(); 19 20 if ($event->name === 'ACTION_ACT_PREPROCESS') { 21 return; 22 } 23 24 $event->stopPropagation(); 25 26 global $INPUT; 27 28 // early output to trigger display msgs even via AJAX. 29 echo ' '; 30 tpl_flush(); 31 if ($INPUT->server->str('REQUEST_METHOD') === 'POST') { 32 try { 33 $this->handlePost(); 34 if ($event->name === 'AJAX_CALL_UNKNOWN') { 35 $this->ajaxSuccess(); // To signal success to AJAX. 36 } else { 37 msg($this->getLang('thanks'), 1); 38 } 39 return; // we're done here 40 } catch (\Exception $e) { 41 msg($e->getMessage(), -1); 42 } 43 } 44 45 echo $this->getForm(); 46 } 47 48 public function handleMenu(Doku_Event $event) 49 { 50 if ($event->data['view'] !== 'page') return; 51 52 array_splice($event->data['items'], -1, 0, [new \dokuwiki\plugin\recommend\MenuItem()]); 53 } 54 /** 55 * Returns rendered form 56 * 57 * @return string 58 */ 59 protected function getForm() 60 { 61 global $INPUT; 62 63 $id = getID(); // we may run in AJAX context 64 if ($id === '') throw new \RuntimeException('No ID given'); 65 66 $form = new \dokuwiki\Form\Form([ 67 'action' => wl($id, ['do' => 'recommend'], false, '&'), 68 'id' => 'plugin__recommend', 69 ]); 70 $form->setHiddenField('id', $id); // we need it for the ajax call 71 72 /** @var helper_plugin_recommend_assignment $helper */ 73 $helper = plugin_load('helper', 'recommend_assignment'); 74 $template = $helper->loadMatchingTemplate(); 75 76 if ($INPUT->server->has('REMOTE_USER')) { 77 global $USERINFO; 78 $form->setHiddenField('s_name', $USERINFO['name']); 79 $form->setHiddenField('s_email', $USERINFO['mail']); 80 } else { 81 $form->addTextInput('s_name', $this->getLang('yourname'))->addClass('edit'); 82 $form->addTextInput('s_email', $this->getLang('youremailaddress'))->addClass('edit'); 83 } 84 85 $recipientEmails = $template['user'] ?? ''; 86 $message = $template['message'] ?? ''; 87 $form->addTextInput('r_email', $this->getLang('recipients'))->addClass('edit')->val($recipientEmails); 88 $form->addTextInput('subject', $this->getLang('subject'))->addClass('edit'); 89 $form->addTextarea('comment', $this->getLang('message')) 90 ->attr('rows', '8') 91 ->attr('cols', '40') 92 ->addClass('edit') 93 ->val($message); 94 95 /** @var helper_plugin_captcha $captcha */ 96 $captcha = plugin_load('helper', 'captcha'); 97 if ($captcha) $form->addHTML($captcha->getHTML()); 98 99 $form->addTagOpen('div')->addClass('buttons'); 100 $form->addButton('submit', $this->getLang('send'))->attr('type', 'submit'); 101 $form->addTagClose('div'); 102 103 return $form->toHTML(); 104 } 105 106 /** 107 * Handles form submission 108 * 109 * @throws Exception 110 */ 111 protected function handlePost() 112 { 113 global $INPUT; 114 115 if (!checkSecurityToken()) { 116 throw new \Exception('Security token did not match'); 117 } 118 119 // Captcha plugin 120 $helper = null; 121 if (@is_dir(DOKU_PLUGIN . 'captcha')) $helper = plugin_load('helper','captcha'); 122 if (!is_null($helper) && $helper->isEnabled() && !$helper->check()) { 123 throw new \Exception($this->getLang('err_captcha')); 124 } 125 126 /* Validate input. */ 127 $recipient = $INPUT->str('r_email'); 128 if (!$recipient || !mail_isvalid($recipient)) { 129 throw new \Exception($this->getLang('err_recipient')); 130 } 131 132 if (!isset($_POST['s_email']) || !mail_isvalid($_POST['s_email'])) { 133 throw new \Exception($this->getLang('err_sendermail')); 134 } 135 if (!isset($_POST['s_name']) || trim($_POST['s_name']) === '') { 136 throw new \Exception($this->getLang('err_sendername')); 137 } 138 $s_name = $_POST['s_name']; 139 $sender = $s_name . ' <' . $_POST['s_email'] . '>'; 140 141 $id = $INPUT->filter('cleanID')->str('id'); 142 if ($id === '' || !page_exists($id)) throw new \Exception($this->getLang('err_page')); 143 144 $comment = $INPUT->str('comment'); 145 146 /* Prepare mail text. */ 147 $mailtext = file_get_contents(dirname(__FILE__).'/template.txt'); 148 149 global $conf; 150 foreach (array('NAME' => $recipient, 151 'PAGE' => $id, 152 'SITE' => $conf['title'], 153 'URL' => wl($id, '', true), 154 'COMMENT' => $comment, 155 'AUTHOR' => $s_name) as $var => $val) { 156 $mailtext = str_replace('@' . $var . '@', $val, $mailtext); 157 } 158 /* Limit to two empty lines. */ 159 $mailtext = preg_replace('/\n{4,}/', "\n\n\n", $mailtext); 160 161 $this->sendMail($recipient, $mailtext, $sender); 162 163 /** @var helper_plugin_recommend_log $log */ 164 $log = new helper_plugin_recommend_log(date('Y-m')); 165 $log->writeEntry($id, $sender, $recipient, $comment); 166 } 167 168 /** 169 * @param string $recipient 170 * @param string $mailtext 171 * @param string $sender 172 * @return void 173 */ 174 protected function sendMail($recipient, $mailtext, $sender) 175 { 176 global $INPUT; 177 178 $mailer = new Mailer(); 179 $mailer->bcc($recipient); 180 $mailer->from($sender); 181 182 $subject = $INPUT->str('subject'); 183 $mailer->subject($subject); 184 $mailer->setBody($mailtext); 185 $mailer->send(); 186 } 187 188 /** 189 * show success message in ajax mode 190 */ 191 protected function ajaxSuccess() 192 { 193 echo '<form id="plugin__recommend" accept-charset="utf-8" method="post" action="?do=recommend">'; 194 echo '<div class="no">'; 195 echo '<span class="ui-icon ui-icon-circle-check" style="float: left; margin: 0 7px 50px 0;"></span>'; 196 echo '<p>' . $this->getLang('done') . '</p>'; 197 echo '<button type="reset" class="button">' . $this->getLang('close') . '</button>'; 198 echo '</div>'; 199 echo '</form>'; 200 } 201} 202