control.php 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. <?php
  2. /**
  3. * The control file of mail module of ZenTaoPMS.
  4. *
  5. * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
  6. * @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
  7. * @author Yangyang Shi <shiyangyang@cnezsoft.com>
  8. * @package mail
  9. * @version $Id$
  10. * @link https://www.zentao.net
  11. */
  12. class mail extends control
  13. {
  14. /**
  15. * Construct.
  16. *
  17. * @access public
  18. * @return void
  19. * @param string $moduleName
  20. * @param string $methodName
  21. */
  22. public function __construct($moduleName = '', $methodName = '')
  23. {
  24. parent::__construct($moduleName, $methodName);
  25. /* Task #1967. check the function of fsocket. */
  26. if(isset($this->config->mail->mta) and !function_exists('fsockopen')) return $this->send(array('result' => 'fail', 'load' => array('alert' => $this->lang->mail->nofsocket, 'locate' => array('back' => true))));
  27. }
  28. /**
  29. * The index page, goto edit page or detect page.
  30. *
  31. * @access public
  32. * @return void
  33. */
  34. public function index()
  35. {
  36. if($this->config->mail->turnon)
  37. {
  38. if($this->config->mail->mta == 'smtp') $this->locate(inlink('edit'));
  39. }
  40. $this->view->title = $this->lang->mail->common . $this->lang->hyphen . $this->lang->mail->index;
  41. $this->display();
  42. }
  43. /**
  44. * Detect email config auto.
  45. *
  46. * @access public
  47. * @return void
  48. */
  49. public function detect()
  50. {
  51. if($_POST)
  52. {
  53. set_time_limit(30);
  54. $error = '';
  55. if($this->post->fromAddress == false) $error = sprintf($this->lang->error->notempty, $this->lang->mail->fromAddress);
  56. if(!$error && !validater::checkEmail($this->post->fromAddress)) $error = sprintf($this->lang->error->email, $this->lang->mail->fromAddress);
  57. if($error) return $this->send(array('result' => 'fail', 'callback' => "zui.Modal.alert({message: '{$error}', icon: 'icon-exclamation-sign', iconClass: 'warning-pale rounded-full icon-2x'});"));
  58. $mailConfig = $this->mail->autoDetect($this->post->fromAddress);
  59. $mailConfig->fromAddress = $this->post->fromAddress;
  60. $mailConfig->domain = common::getSysURL();
  61. $this->session->set('mailConfig', $mailConfig);
  62. $response['load'] = inlink('edit');
  63. return $this->sendSuccess($response);
  64. }
  65. $this->view->title = $this->lang->mail->common . $this->lang->hyphen . $this->lang->mail->detect;
  66. $this->view->fromAddress = isset($this->session->mailConfig->fromAddress) ? $this->session->mailConfig->fromAddress : '';
  67. $this->display();
  68. }
  69. /**
  70. * Edit the mail config.
  71. *
  72. * @access public
  73. * @return void
  74. */
  75. public function edit()
  76. {
  77. $mailConfig = $this->mailZen->getConfigForEdit();
  78. if(empty($mailConfig)) $this->locate(inlink('detect'));
  79. $this->view->title = $this->lang->mail->common . $this->lang->hyphen . $this->lang->mail->edit;
  80. $this->view->mailExist = $this->mail->mailExist();
  81. $this->view->mailConfig = $mailConfig;
  82. $this->view->openssl = extension_loaded('openssl');
  83. $this->display();
  84. }
  85. /**
  86. * Save the email config.
  87. *
  88. * @access public
  89. * @return void
  90. */
  91. public function save()
  92. {
  93. if(!empty($_POST))
  94. {
  95. $mailConfig = $this->mailZen->getConfigForSave();
  96. if($mailConfig->turnon && empty($mailConfig->fromName)) return $this->sendError(array('fromName' => sprintf($this->lang->error->notempty, $this->lang->mail->fromName)));
  97. /* The mail need openssl and curl extension when secure is tls. */
  98. if($mailConfig->smtp->secure == 'tls')
  99. {
  100. if(!extension_loaded('openssl')) return $this->sendError($this->lang->mail->noOpenssl);
  101. if(!extension_loaded('curl')) return $this->sendError($this->lang->mail->noCurl);
  102. }
  103. $this->session->set('mailConfig', $mailConfig);
  104. $this->loadModel('setting')->setItems('system.mail', $mailConfig);
  105. if(dao::isError()) return $this->sendError(dao::getError());
  106. if($mailConfig->turnon)
  107. {
  108. $mailExist = !empty($this->mail->mailExist());
  109. return $this->send(array('result' => 'success', 'callback' => "window.mailTips({$mailExist})"));
  110. }
  111. }
  112. return $this->sendSuccess(array('load' => inLink('detect')));
  113. }
  114. /**
  115. * Send test email.
  116. *
  117. * @access public
  118. * @return void
  119. */
  120. public function test()
  121. {
  122. if(!$this->config->mail->turnon) return $this->sendError($this->lang->mail->needConfigure);
  123. if($_POST)
  124. {
  125. /* The mail need openssl and curl extension when secure is tls. */
  126. if(isset($this->config->mail->async)) $this->config->mail->async = 0;
  127. if($this->config->mail->smtp->secure == 'tls')
  128. {
  129. if(!extension_loaded('openssl')) return $this->sendError($this->lang->mail->noOpenssl);
  130. if(!extension_loaded('curl')) return $this->sendError($this->lang->mail->noCurl);
  131. }
  132. $this->mail->send($this->post->to, $this->lang->mail->testSubject, $this->lang->mail->testContent, '', true);
  133. if($this->mail->isError()) return $this->sendError(array('error' => implode("\n", $this->mail->getError())));
  134. return $this->sendSuccess(array('load' => inLink('test'), 'message' => $this->lang->mail->noticeResend));
  135. }
  136. $this->view->title = $this->lang->mail->common . $this->lang->hyphen . $this->lang->mail->test;
  137. $this->view->users = $this->mailZen->getHasMailUserPairs();
  138. $this->display();
  139. }
  140. /**
  141. * Reset the email config.
  142. *
  143. * @access public
  144. * @return void
  145. */
  146. public function reset()
  147. {
  148. $this->loadModel('setting')->deleteItems('module=mail');
  149. unset($_SESSION['mailConfig']);
  150. return $this->sendSuccess(array('load' => inlink('detect')));
  151. }
  152. /**
  153. * Async send mail.
  154. *
  155. * @access public
  156. * @return void
  157. */
  158. public function asyncSend()
  159. {
  160. /* Reload mail config. */
  161. unset(router::$loadedConfigs['mail']);
  162. $this->loadModel('common')->loadConfigFromDB();
  163. $this->app->loadConfig('mail');
  164. if(!$this->config->mail->turnon) return false;
  165. mailModel::$instance = null;
  166. $this->mail->setMTA();
  167. $queueList = $this->mail->getQueue('wait', 'id_asc');
  168. if(isset($this->config->mail->async))$this->config->mail->async = 0;
  169. foreach($queueList as $queue)
  170. {
  171. $log = $this->mailZen->sendQueue($queue, true);
  172. if($log) echo $log['message'];
  173. }
  174. /* Delete sended mail. */
  175. $this->mailZen->deleteSentQueue();
  176. echo "OK\n";
  177. }
  178. /**
  179. * Resend fail mails.
  180. *
  181. * @access public
  182. * @return void
  183. * @param int $queueID
  184. */
  185. public function resend($queueID)
  186. {
  187. $queue = $this->mail->getQueueById($queueID);
  188. if($queue and $queue->status == 'sended') return $this->sendSuccess(array('message' => $this->lang->mail->noticeResend, 'load' => true));
  189. if(isset($this->config->mail->async)) $this->config->mail->async = 0;
  190. $log = $this->mailZen->sendQueue($queue);
  191. if($log && $log['result'] == 'fail') return $this->send(array('result' => 'fail', 'callback' => "zui.Modal.alert(" . json_encode(array('message' => array('html' => str_replace("\n", '<br />', $log['message'])))) . ")"));
  192. return $this->sendSuccess(array('result' => 'success', 'message' => $this->lang->mail->noticeResend, 'load' => true));
  193. }
  194. /**
  195. * Browse mail queue.
  196. *
  197. * @param string $orderBy
  198. * @param int $recTotal
  199. * @param int $recPerPage
  200. * @param int $pageID
  201. * @access public
  202. * @return void
  203. */
  204. public function browse($orderBy = 'id_desc', $recTotal = 0, $recPerPage = 100, $pageID = 1)
  205. {
  206. $this->app->loadClass('pager', $static = true);
  207. $pager = new pager($recTotal, $recPerPage, $pageID);
  208. $queueList = $this->mail->getQueue('all', $orderBy, $pager, false);
  209. foreach($queueList as $queue) $queue->toList .= ',' . $queue->ccList;
  210. $this->view->title = $this->lang->mail->browse;
  211. $this->view->queueList = $queueList;
  212. $this->view->pager = $pager;
  213. $this->view->orderBy = $orderBy;
  214. $this->view->users = $this->loadModel('user')->getPairs('noletter');
  215. $this->display();
  216. }
  217. /**
  218. * Delete mail queue.
  219. *
  220. * @param int $id
  221. * @param string $confirm
  222. * @access public
  223. * @return void
  224. */
  225. public function delete($id)
  226. {
  227. $this->dao->delete()->from(TABLE_NOTIFY)->where('id')->eq($id)->exec();
  228. return $this->send(array('result' => 'success', 'callback' => 'loadCurrentPage()'));
  229. }
  230. /**
  231. * Batch delete mail queue.
  232. *
  233. * @access public
  234. * @return void
  235. */
  236. public function batchDelete()
  237. {
  238. $idList = implode('|', $this->post->mailIdList);
  239. if(empty($idList)) return $this->send(array('result' => 'fail', 'load' => true));
  240. /* Get deleted ID list from query string. */
  241. $this->dao->delete()->from(TABLE_NOTIFY)->where('id')->in($idList)->exec();
  242. return $this->send(array('result' => 'success', 'callback' => 'loadCurrentPage()'));
  243. }
  244. }