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 if ($INPUT->server->has('REMOTE_USER')) { 73 global $USERINFO; 74 $form->setHiddenField('s_name', $USERINFO['name']); 75 $form->setHiddenField('s_email', $USERINFO['mail']); 76 } else { 77 $form->addTextInput('s_name', $this->getLang('yourname'))->addClass('edit'); 78 $form->addTextInput('s_email', $this->getLang('youremailaddress'))->addClass('edit'); 79 } 80 81 $form->addTextInput('r_email', $this->getLang('recipients'))->addClass('edit'); 82 $form->addTextInput('subject', $this->getLang('subject'))->addClass('edit'); 83 $form->addTextarea('comment', $this->getLang('message'))->attr('rows', '8')->attr('cols', '40')->addClass('edit'); 84 85 /** @var helper_plugin_captcha $captcha */ 86 $captcha = plugin_load('helper', 'captcha'); 87 if ($captcha) $form->addHTML($captcha->getHTML()); 88 89 $form->addTagOpen('div')->addClass('buttons'); 90 $form->addButton('submit', $this->getLang('send'))->attr('type', 'submit'); 91 $form->addTagClose('div'); 92 93 return $form->toHTML(); 94 } 95 96 /** 97 * Handles form submission 98 * 99 * @throws Exception 100 */ 101 protected function handlePost() 102 { 103 global $INPUT; 104 105 if (!checkSecurityToken()) { 106 throw new \Exception('Security token did not match'); 107 } 108 109 // Captcha plugin 110 $helper = null; 111 if (@is_dir(DOKU_PLUGIN . 'captcha')) $helper = plugin_load('helper','captcha'); 112 if (!is_null($helper) && $helper->isEnabled() && !$helper->check()) { 113 throw new \Exception($this->getLang('err_captcha')); 114 } 115 116 /* Validate input. */ 117 $recipient = $INPUT->str('r_email'); 118 if (!$recipient || !mail_isvalid($recipient)) { 119 throw new \Exception($this->getLang('err_recipient')); 120 } 121 122 if (!isset($_POST['s_email']) || !mail_isvalid($_POST['s_email'])) { 123 throw new \Exception($this->getLang('err_sendermail')); 124 } 125 if (!isset($_POST['s_name']) || trim($_POST['s_name']) === '') { 126 throw new \Exception($this->getLang('err_sendername')); 127 } 128 $s_name = $_POST['s_name']; 129 $sender = $s_name . ' <' . $_POST['s_email'] . '>'; 130 131 $id = $INPUT->filter('cleanID')->str('id'); 132 if ($id === '' || !page_exists($id)) throw new \Exception($this->getLang('err_page')); 133 134 $comment = $INPUT->str('comment'); 135 136 /* Prepare mail text. */ 137 $mailtext = file_get_contents(dirname(__FILE__).'/template.txt'); 138 139 global $conf; 140 foreach (array('NAME' => $recipient, 141 'PAGE' => $id, 142 'SITE' => $conf['title'], 143 'URL' => wl($id, '', true), 144 'COMMENT' => $comment, 145 'AUTHOR' => $s_name) as $var => $val) { 146 $mailtext = str_replace('@' . $var . '@', $val, $mailtext); 147 } 148 /* Limit to two empty lines. */ 149 $mailtext = preg_replace('/\n{4,}/', "\n\n\n", $mailtext); 150 151 $this->sendMail($recipient, $mailtext, $sender); 152 153 /** @var helper_plugin_recommend_log $log */ 154 $log = new helper_plugin_recommend_log(date('Y-m')); 155 $log->writeEntry($id, $sender, $recipient, $comment); 156 } 157 158 /** 159 * @param string $recipient 160 * @param string $mailtext 161 * @param string $sender 162 * @return void 163 */ 164 protected function sendMail($recipient, $mailtext, $sender) 165 { 166 global $INPUT; 167 168 $mailer = new Mailer(); 169 $mailer->bcc($recipient); 170 $mailer->from($sender); 171 172 $subject = $INPUT->str('subject'); 173 $mailer->subject($subject); 174 $mailer->setBody($mailtext); 175 $mailer->send(); 176 } 177 178 /** 179 * show success message in ajax mode 180 */ 181 protected function ajaxSuccess() 182 { 183 echo '<form id="plugin__recommend" accept-charset="utf-8" method="post" action="?do=recommend">'; 184 echo '<div class="no">'; 185 echo '<span class="ui-icon ui-icon-circle-check" style="float: left; margin: 0 7px 50px 0;"></span>'; 186 echo '<p>' . $this->getLang('done') . '</p>'; 187 echo '<button type="reset" class="button">' . $this->getLang('close') . '</button>'; 188 echo '</div>'; 189 echo '</form>'; 190 } 191} 192