WecomCenterSave.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. <?php declare(strict_types = 0);
  2. /*
  3. ** WeCom Center - POST controller. Dispatches actions and redirects back.
  4. */
  5. namespace Modules\WecomCenter\Actions;
  6. use CController;
  7. use CControllerResponseRedirect;
  8. use CUrl;
  9. use CWebUser;
  10. use Exception;
  11. use Modules\WecomCenter\Lib\Helper;
  12. use Modules\WecomCenter\Lib\I18n;
  13. class WecomCenterSave extends CController {
  14. protected function init() {
  15. $this->disableCsrfValidation();
  16. }
  17. protected function checkInput() {
  18. return true;
  19. }
  20. protected function checkPermissions() {
  21. return CWebUser::getType() == USER_TYPE_SUPER_ADMIN;
  22. }
  23. protected function doAction() {
  24. $mediatypeid = (string) ($_REQUEST['mediatypeid'] ?? '');
  25. $hostid = (string) ($_REQUEST['hostid'] ?? '');
  26. try {
  27. // One-click alert scheme presets: buttons named scheme_<key>.
  28. $applied = false;
  29. foreach (array_keys(Helper::SCHEMES) as $k) {
  30. if (isset($_REQUEST['scheme_'.$k])) {
  31. $this->applyScheme($mediatypeid, $k);
  32. $applied = true;
  33. break;
  34. }
  35. }
  36. if (!$applied) {
  37. $op = (string) ($_REQUEST['op'] ?? '');
  38. switch ($op) {
  39. case 'save_alert':
  40. $this->saveAlert($mediatypeid);
  41. break;
  42. case 'save_triggers':
  43. $this->saveTriggers();
  44. break;
  45. case 'save_robot':
  46. $this->saveRobot($mediatypeid);
  47. break;
  48. case 'test_robot':
  49. $this->testRobot($mediatypeid);
  50. break;
  51. case 'import_template':
  52. $this->importTemplate();
  53. break;
  54. case 'save_map':
  55. $this->saveMap();
  56. break;
  57. default:
  58. error(I18n::t('msg.unknown_op'));
  59. }
  60. }
  61. }
  62. catch (Exception $e) {
  63. error($e->getMessage());
  64. }
  65. $url = (new CUrl('zabbix.php'))->setArgument('action', 'wecom.center.view');
  66. if ($mediatypeid !== '') {
  67. $url->setArgument('mediatypeid', $mediatypeid);
  68. }
  69. if ($hostid !== '') {
  70. $url->setArgument('hostid', $hostid);
  71. }
  72. $this->setResponse(new CControllerResponseRedirect($url));
  73. }
  74. private function userName(): string {
  75. $n = trim((string) ($_REQUEST['username'] ?? ''));
  76. return $n !== '' ? $n : 'wecomrobot';
  77. }
  78. private function applyScheme(string $mediatypeid, string $scheme): void {
  79. if (!array_key_exists($scheme, Helper::SCHEMES)) {
  80. throw new Exception(I18n::t('msg.bad_scheme'));
  81. }
  82. [$mask, $active] = Helper::SCHEMES[$scheme];
  83. $user = Helper::ensureRobotUser($this->userName());
  84. Helper::applyMedia($user['userid'], $mediatypeid, $mask, $active);
  85. info(I18n::t('msg.scheme_applied', [I18n::t('scheme.'.$scheme)]));
  86. }
  87. private function saveAlert(string $mediatypeid): void {
  88. $active = isset($_REQUEST['enabled']) ? 0 : 1; // media: 0=enabled, 1=disabled
  89. $indices = [];
  90. for ($i = 1; $i <= 6; $i++) {
  91. if (isset($_REQUEST['sev_'.$i])) {
  92. $indices[] = $i;
  93. }
  94. }
  95. $mask = Helper::severityMask($indices);
  96. if ($mask === 0 && $active === 0) {
  97. $mask = 2; // keep at least Information when enabled
  98. }
  99. $user = Helper::ensureRobotUser($this->userName());
  100. $sendto = (string) ($_REQUEST['sendto'] ?? 'WeCom');
  101. Helper::applyMedia($user['userid'], $mediatypeid, $mask, $active, $sendto);
  102. info(I18n::t('msg.saved'));
  103. }
  104. private function saveRobot(string $mediatypeid): void {
  105. $url = trim((string) ($_REQUEST['webhook_url'] ?? ''));
  106. if ($url !== '') {
  107. Helper::setWebhookKey($url);
  108. }
  109. $user = Helper::ensureRobotUser($this->userName());
  110. $cur = Helper::currentMedia($user, $mediatypeid);
  111. $mask = $cur['severity'] ?? 48;
  112. $active = $cur['active'] ?? 0;
  113. $sendto = (string) ($_REQUEST['sendto'] ?? ($cur['sendto'] ?? 'WeCom'));
  114. Helper::applyMedia($user['userid'], $mediatypeid, $mask, $active, $sendto);
  115. info(I18n::t('msg.robot_saved'));
  116. }
  117. private function testRobot(string $mediatypeid): void {
  118. $mt = Helper::getMediatype($mediatypeid);
  119. if (!$mt) {
  120. throw new Exception(I18n::t('msg.no_mediatype'));
  121. }
  122. $url = Helper::webhookUrl($mt);
  123. if ($url === '') {
  124. throw new Exception(I18n::t('msg.no_url'));
  125. }
  126. $text = '['.I18n::t('page.title').'] Test OK - '.date('Y-m-d H:i:s');
  127. $res = Helper::testWebhook($url, $text);
  128. $body = (string) $res['body'];
  129. $ok = (strpos($body, '"errcode":0') !== false) || (strpos($body, '"errcode": 0') !== false);
  130. if ($ok) {
  131. info(I18n::t('msg.tested'));
  132. }
  133. else {
  134. error(I18n::t('msg.test_failed', [$res['status'], $body]));
  135. }
  136. }
  137. private function importTemplate(): void {
  138. $file = (string) ($_REQUEST['template_file'] ?? '');
  139. if ($file === '') {
  140. throw new Exception(I18n::t('msg.no_template'));
  141. }
  142. $module_dir = dirname(__DIR__);
  143. $res = Helper::importTemplate($module_dir, $file);
  144. $n = isset($res['templates']) && is_array($res['templates']) ? count($res['templates']) : 0;
  145. info(I18n::t('msg.imported', [$n]));
  146. }
  147. private function saveTriggers(): void {
  148. $ids = (string) ($_REQUEST['trig_ids'] ?? '');
  149. $ids = array_filter(array_map('trim', explode(',', $ids)));
  150. if (!$ids) {
  151. throw new Exception(I18n::t('msg.no_triggers'));
  152. }
  153. $map = [];
  154. foreach ($ids as $id) {
  155. $id = (string) (int) $id;
  156. if ($id === '' || $id === '0') {
  157. continue;
  158. }
  159. // checked => alerting enabled => trigger status 0; unchecked => disabled => 1
  160. $map[$id] = isset($_REQUEST['trig_'.$id]) ? 0 : 1;
  161. }
  162. $n = Helper::setTriggersStatus($map);
  163. info(I18n::t('msg.triggers_saved', [$n]));
  164. }
  165. private function saveMap(): void {
  166. $hostid = (string) ($_REQUEST['hostid'] ?? '');
  167. $lat = trim((string) ($_REQUEST['lat'] ?? ''));
  168. $lon = trim((string) ($_REQUEST['lon'] ?? ''));
  169. if ($hostid === '') {
  170. throw new Exception(I18n::t('msg.no_host'));
  171. }
  172. Helper::setHostLocation($hostid, $lat, $lon);
  173. info(I18n::t('msg.map_saved'));
  174. }
  175. }