api.darkvoid.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. <?php
  2. /**
  3. * Notification area aka DarkVoid class
  4. */
  5. class DarkVoid {
  6. /**
  7. *
  8. * Contains system alter config as key=>value
  9. *
  10. * @var array
  11. */
  12. protected $altCfg = array();
  13. /**
  14. * Contains current user login
  15. *
  16. * @var string
  17. */
  18. protected $myLogin = '';
  19. /**
  20. * Contains alerts cache
  21. *
  22. * @var string
  23. */
  24. protected $alerts = '';
  25. /**
  26. * Contains non-cachable alerts & notifications
  27. *
  28. * @var string
  29. */
  30. protected $dynamicArea = '';
  31. /**
  32. * Contains default cache timeout in minutes
  33. *
  34. * @var int
  35. */
  36. protected $cacheTime = '10';
  37. /**
  38. * UbillingConfig object placeholder
  39. *
  40. * @var object
  41. */
  42. protected $ubConfig = null;
  43. /**
  44. * Array of modules that must be skipped on alert updates
  45. *
  46. * @var array
  47. */
  48. protected $skipOnModules = array();
  49. /**
  50. * Contains current module
  51. *
  52. * @var string
  53. */
  54. protected $currentModule = '';
  55. /**
  56. * Cache storage path
  57. */
  58. const CACHE_PATH = 'exports/';
  59. /**
  60. * Cache prefix
  61. */
  62. const CACHE_PREFIX = 'darkvoid.';
  63. public function __construct() {
  64. if (LOGGED_IN) {
  65. $this->setCurrentModule();
  66. $this->setModSkip();
  67. $this->setMyLogin();
  68. $this->loadAlter();
  69. $this->loadAlerts();
  70. $this->loadDynamicArea();
  71. }
  72. }
  73. /**
  74. * Sets current instance current route module name
  75. *
  76. * @return void
  77. */
  78. protected function setCurrentModule() {
  79. if (ubRouting::checkGet('module')) {
  80. $this->currentModule = ubRouting::get('module', 'vf');
  81. }
  82. }
  83. /**
  84. * Sets modules array to be skipped on alert updates to prevent DB ops
  85. *
  86. * @return void
  87. */
  88. protected function setModSkip() {
  89. $this->skipOnModules = array('turbosms', 'senddog', 'remoteapi', 'updatemanager');
  90. $this->skipOnModules = array_flip($this->skipOnModules);
  91. }
  92. /**
  93. * Loads alerts from per-user cache or from database if needed
  94. *
  95. * @return void
  96. */
  97. protected function loadAlerts() {
  98. $cacheName = self::CACHE_PATH . self::CACHE_PREFIX . $this->myLogin;
  99. $cacheTime = time() - ($this->cacheTime * 60); //in minutes
  100. $updateCache = false;
  101. if (file_exists($cacheName)) {
  102. $updateCache = false;
  103. if ((filemtime($cacheName) > $cacheTime)) {
  104. $updateCache = false;
  105. } else {
  106. $updateCache = true;
  107. }
  108. } else {
  109. $updateCache = true;
  110. }
  111. if ($updateCache) {
  112. //ugly hack to prevent alerts update on tsms and senddog modules
  113. if (!empty($this->currentModule)) {
  114. if (!isset($this->skipOnModules[$this->currentModule])) {
  115. //renew cache
  116. $this->updateAlerts();
  117. }
  118. } else {
  119. //renew cache
  120. $this->updateAlerts();
  121. }
  122. } else {
  123. //read from cache
  124. @$this->alerts = file_get_contents($cacheName);
  125. }
  126. }
  127. /**
  128. * Loads dynamic, non-cachable dark-void conten
  129. *
  130. * @return void
  131. */
  132. protected function loadDynamicArea() {
  133. //Taskbar quick search
  134. if (isset($this->altCfg['TB_QUICKSEARCH_ENABLED'])) {
  135. if ($this->altCfg['TB_QUICKSEARCH_ENABLED']) {
  136. if (@$this->altCfg['TB_QUICKSEARCH_INLINE'] == 1) {
  137. if ($this->currentModule == 'taskbar' or empty($this->currentModule)) {
  138. $this->dynamicArea .= web_TaskBarQuickSearchForm();
  139. //overriding default style
  140. $this->dynamicArea .= wf_tag('style');
  141. $this->dynamicArea .= '
  142. .tbqsearchform {
  143. float: right;
  144. margin-right: 0px;
  145. margin-left: 5px;
  146. position: relative;
  147. display: flex;
  148. align-items: center;
  149. }
  150. ';
  151. $this->dynamicArea .= wf_tag('style', true);
  152. }
  153. }
  154. }
  155. }
  156. }
  157. /**
  158. * Sets private login property
  159. *
  160. * @return
  161. */
  162. protected function setMyLogin() {
  163. $this->myLogin = whoami();
  164. }
  165. /**
  166. * Loads global alter.ini config into protected property
  167. *
  168. * @global type $ubillingConfig
  169. * @return void
  170. */
  171. protected function loadAlter() {
  172. global $ubillingConfig;
  173. $this->ubConfig = $ubillingConfig;
  174. $this->altCfg = $ubillingConfig->getAlter();
  175. if (isset($this->altCfg['DARKVOID_CACHETIME'])) {
  176. if ($this->altCfg['DARKVOID_CACHETIME']) {
  177. $this->cacheTime = $this->altCfg['DARKVOID_CACHETIME'];
  178. }
  179. }
  180. }
  181. /**
  182. * Renders available and enabled alerts into DarkVoid notification area
  183. *
  184. * @return void
  185. */
  186. protected function updateAlerts() {
  187. //new tickets alert
  188. if ($this->altCfg['TB_NEWTICKETNOTIFY']) {
  189. $newticketcount = zb_TicketsGetAllNewCount();
  190. if ($newticketcount != 0) {
  191. $this->alerts .= wf_Link('?module=ticketing', wf_img('skins/ticketnotify.gif', $newticketcount . ' ' . __('support tickets expected processing')), false);
  192. }
  193. }
  194. //new signups notification
  195. if ($this->altCfg['SIGREQ_ENABLED']) {
  196. $signups = new SignupRequests();
  197. $newreqcount = $signups->getAllNewCount();
  198. if ($newreqcount != 0) {
  199. $this->alerts .= wf_Link('?module=sigreq', wf_img('skins/sigreqnotify.gif', $newreqcount . ' ' . __('signup requests expected processing')), false);
  200. }
  201. }
  202. //check for unread messages in instant messanger
  203. if ($this->altCfg['TB_UBIM']) {
  204. if (cfr('UBIM')) {
  205. $ubIm = new UBMessenger();
  206. $unreadMessageCount = $ubIm->checkForUnreadMessages();
  207. if ($unreadMessageCount) {
  208. //yes, we have new messages
  209. $unreadIMNotify = __('You received') . ' ' . $unreadMessageCount . ' ' . __('new messages');
  210. $this->alerts .= wf_Link($ubIm::URL_ME . '&' . $ubIm::ROUTE_REFRESH . '=true', wf_img("skins/ubim_blink.gif", $unreadMessageCount . ' ' . __('new message received')), false, '');
  211. }
  212. }
  213. }
  214. //check sms sending queue
  215. if ($this->altCfg['SENDDOG_ENABLED']) {
  216. $smsQueueCount = rcms_scandir(DATA_PATH . 'tsms/');
  217. $smsQueueCount = sizeof($smsQueueCount);
  218. if ($smsQueueCount > 0) {
  219. $this->alerts .= wf_Link('?module=tsmsqueue', wf_img('skins/sms.png', $smsQueueCount . ' ' . __('SMS in queue')), false, '');
  220. }
  221. if ($this->altCfg['SENDDOG_PARALLEL_MODE']) {
  222. $sendDogPid = SendDog::PID_PATH;
  223. if (file_exists($sendDogPid)) {
  224. $this->alerts .= wf_Link('?module=tsmsqueue', wf_img('skins/dog_stand.png', __('SendDog is working')), false, '');
  225. }
  226. }
  227. }
  228. //police dog alerts
  229. if ($this->altCfg['POLICEDOG_ENABLED']) {
  230. $policeDogQuery = "SELECT COUNT(`id`) from `policedogalerts`";
  231. $policeDogCount = simple_query($policeDogQuery);
  232. $policeDogCount = $policeDogCount['COUNT(`id`)'];
  233. if ($policeDogCount > 0) {
  234. $this->alerts .= wf_Link('?module=policedog&show=fastscan', wf_img('skins/policedogalert.png', $policeDogCount . ' ' . __('Wanted MAC detected')), false, '');
  235. }
  236. }
  237. if ($this->altCfg['TB_TASKMANNOTIFY']) {
  238. //only "for me" tasks notification
  239. if ($this->altCfg['TB_TASKMANNOTIFY'] == 1) {
  240. $undoneTasksCount = ts_GetUndoneCountersMy();
  241. if ($undoneTasksCount > 0) {
  242. $undoneAlert = $undoneTasksCount . ' ' . __('Undone tasks') . ' ' . __('for me');
  243. $this->alerts .= wf_Link("?module=taskman&show=undone", wf_img("skins/jobnotify.png", $undoneAlert), false, '');
  244. }
  245. }
  246. //total undone tasks count notification
  247. if ($this->altCfg['TB_TASKMANNOTIFY'] == 2) {
  248. $undoneTasksCount = ts_GetUndoneCountersAll();
  249. if ($undoneTasksCount > 0) {
  250. $undoneAlert = $undoneTasksCount . ' ' . __('Undone tasks') . ' ' . __('for all');
  251. $this->alerts .= wf_Link("?module=taskman&show=undone", wf_img("skins/jobnotify.png", $undoneAlert), false, '');
  252. }
  253. }
  254. //total+my undone tasks count notification
  255. if ($this->altCfg['TB_TASKMANNOTIFY'] == 3) {
  256. $undoneTasksCount = ts_GetUndoneCountersAll();
  257. if ($undoneTasksCount > 0) {
  258. $undoneTasksCountMy = ts_GetUndoneCountersMy();
  259. $undoneAlert = $undoneTasksCount . ' ' . __('Undone tasks') . ': ' . __('for all') . ' ' . ($undoneTasksCount - $undoneTasksCountMy) . ' / ' . __('for me') . ' ' . $undoneTasksCountMy;
  260. $this->alerts .= wf_Link("?module=taskman&show=undone", wf_img("skins/jobnotify.png", $undoneAlert), false, '');
  261. }
  262. }
  263. }
  264. //missed calls notification
  265. if (@$this->altCfg['WDYC_ENABLED']) {
  266. $wdycCache = 'exports/whydoyoucall.dat';
  267. if (file_exists($wdycCache)) {
  268. $cacheData = file_get_contents($wdycCache);
  269. if (!empty($wdycCache)) {
  270. $cacheData = unserialize($cacheData);
  271. $missedCallsCount = sizeof($cacheData);
  272. if ($missedCallsCount > 0) {
  273. $missedCallsAlert = $missedCallsCount . ' ' . __('users tried to contact you but could not');
  274. $this->alerts .= wf_Link('?module=whydoyoucall', wf_img("skins/wdycnotify.png", $missedCallsAlert), false, '');
  275. }
  276. }
  277. }
  278. }
  279. //callback services
  280. if (@$this->altCfg['CALLMEBACK_ENABLED']) {
  281. $callMeBack = new CallMeBack();
  282. $undoneCallsCount = $callMeBack->getUndoneCount();
  283. if ($undoneCallsCount > 0) {
  284. $callmeBackAlert = $undoneCallsCount . ' ' . __('Users are waiting for your call');
  285. $this->alerts .= wf_Link('?module=callmeback', wf_img("skins/cmbnotify.png", $callmeBackAlert), false, '');
  286. }
  287. }
  288. //NAS servers monitoring
  289. if (isset($this->altCfg['NASMON_ENABLED'])) {
  290. if ($this->altCfg['NASMON_ENABLED']) {
  291. $nasMon = new NasMon();
  292. $this->alerts .= $nasMon->getNasAlerts();
  293. }
  294. }
  295. //watchdog maintenance mode notification
  296. if (isset($this->altCfg['WATCHDOG_ENABLED'])) {
  297. if ($this->altCfg['WATCHDOG_ENABLED']) {
  298. $watchDogMaintenance = zb_StorageGet('WATCHDOG_MAINTENANCE');
  299. $watchDogSmsSilence = zb_StorageGet('WATCHDOG_SMSSILENCE');
  300. if ($watchDogMaintenance) {
  301. $this->alerts .= wf_Link('?module=watchdog', wf_img('skins/maintenance.png', __('Watchdog') . ': ' . __('Disabled')));
  302. }
  303. if ($watchDogSmsSilence) {
  304. $this->alerts .= wf_Link('?module=watchdog', wf_img('skins/smssilence.png', __('Watchdog') . ': ' . __('SMS silence')));
  305. }
  306. }
  307. }
  308. //switchmon at notify area
  309. if ($this->altCfg['TB_SWITCHMON']) {
  310. $dead_raw = zb_StorageGet('SWDEAD');
  311. $last_pingtime = zb_StorageGet('SWPINGTIME');
  312. if (!is_numeric($last_pingtime)) {
  313. $last_pingtime = 0;
  314. }
  315. $deathTime = zb_SwitchesGetAllDeathTime();
  316. $deadarr = array();
  317. $content = '';
  318. if ($this->altCfg['SWYMAP_ENABLED']) {
  319. $content = wf_Link('?module=switchmap', wf_img('skins/swmapsmall.png', __('Switches map')), false);
  320. }
  321. $content .= wf_AjaxLoader() . wf_AjaxLink("?module=switches&forcereping=true&ajaxping=true", wf_img('skins/refresh.gif', __('Force ping')), 'switchping', true, '');
  322. if ($dead_raw) {
  323. $deadarr = unserialize($dead_raw);
  324. if (!empty($deadarr)) {
  325. //there is some dead switches
  326. $deadcount = sizeof($deadarr);
  327. if ($this->altCfg['SWYMAP_ENABLED']) {
  328. //getting geodata
  329. $switchesGeo = zb_SwitchesGetAllGeo();
  330. }
  331. //ajax container
  332. $content .= wf_tag('div', false, '', 'id="switchping"');
  333. foreach ($deadarr as $ip => $switch) {
  334. if ($this->altCfg['SWYMAP_ENABLED']) {
  335. if (isset($switchesGeo[$ip])) {
  336. if (!empty($switchesGeo[$ip])) {
  337. $devicefind = wf_Link('?module=switchmap&finddevice=' . $switchesGeo[$ip], wf_img('skins/icon_search_small.gif', __('Find on map'))) . ' ';
  338. } else {
  339. $devicefind = '';
  340. }
  341. } else {
  342. $devicefind = '';
  343. }
  344. } else {
  345. $devicefind = '';
  346. }
  347. //check morgue records for death time
  348. if (isset($deathTime[$ip])) {
  349. $deathClock = wf_img('skins/clock.png', __('Switch dead since') . ' ' . $deathTime[$ip]) . ' ';
  350. } else {
  351. $deathClock = '';
  352. }
  353. //switch location link
  354. $switchLocator = wf_Link('?module=switches&gotoswitchbyip=' . $ip, web_edit_icon(__('Go to switch')));
  355. //add switch as dead
  356. $content .= $devicefind . ' ' . $switchLocator . ' ' . $deathClock . $ip . ' - ' . $switch . '<br>';
  357. }
  358. //ajax container end
  359. $content .= wf_delimiter() . __('Cache state at time') . ': ' . date("H:i:s", $last_pingtime) . wf_tag('div', true);
  360. $this->alerts .= wf_tag('div', false, 'ubButton') . wf_modal(__('Dead switches') . ': ' . $deadcount, __('Dead switches'), $content, '', '500', '400') . wf_tag('div', true);
  361. } else {
  362. $content .= wf_tag('div', false, '', 'id="switchping"') . __('Switches are okay, everything is fine - I guarantee') . wf_delimiter() . __('Cache state at time') . ': ' . date("H:i:s", $last_pingtime) . wf_tag('div', true);
  363. $this->alerts .= wf_tag('div', false, 'ubButton') . wf_modal(__('All switches alive'), __('All switches alive'), $content, '', '500', '400') . wf_tag('div', true);
  364. }
  365. } else {
  366. $content .= wf_tag('div', false, '', 'id="switchping"') . __('Switches are okay, everything is fine - I guarantee') . wf_delimiter() . __('Cache state at time') . ': ' . @date("H:i:s", $last_pingtime) . wf_tag('div', true);
  367. $this->alerts .= wf_tag('div', false, 'ubButton') . wf_modal(__('All switches alive'), __('All switches alive'), $content, '', '500', '400') . wf_tag('div', true);
  368. }
  369. }
  370. //ForWhotTheBellTolls notification widget
  371. if (isset($this->altCfg['FWTBT_ENABLED'])) {
  372. if ($this->altCfg['FWTBT_ENABLED']) {
  373. $fwtbtFront = new ForWhomTheBellTolls();
  374. $this->alerts .= $fwtbtFront->renderWidget();
  375. }
  376. }
  377. //Dreamkas notification
  378. if ($this->ubConfig->getAlterParam('DREAMKAS_ENABLED') and $this->ubConfig->getAlterParam('DREAMKAS_NOTIFICATIONS_ENABLED')) {
  379. $dsNotifyFront = new DreamKasNotifications();
  380. $this->alerts .= $dsNotifyFront->renderWidget();
  381. }
  382. //I hope this service died.
  383. if ($this->ubConfig->getAlterParam('INSURANCE_ENABLED')) {
  384. $insurance = new Insurance(false);
  385. $hinsReqCount = $insurance->getUnprocessedHinsReqCount();
  386. if ($hinsReqCount > 0) {
  387. $insuranceRequestsAlert = $hinsReqCount . ' ' . __('insurance requests waiting for your reaction');
  388. $this->alerts .= wf_Link($insurance::URL_ME, wf_img('skins/insurance_notify.png', $insuranceRequestsAlert));
  389. }
  390. }
  391. //aerial alerts basic notification
  392. if ($this->ubConfig->getAlterParam('AERIAL_ALERTS_ENABLED')) {
  393. if ($this->ubConfig->getAlterParam('AERIAL_ALERTS_NOTIFY')) {
  394. $monitorRegion = $this->ubConfig->getAlterParam('AERIAL_ALERTS_NOTIFY');
  395. $aerialAlerts = new AerialAlerts($monitorRegion);
  396. $regionAlert = $aerialAlerts->renderRegionNotification($monitorRegion);
  397. if (!empty($regionAlert)) {
  398. $this->alerts .= $regionAlert;
  399. }
  400. }
  401. }
  402. //appending some debug string to validate cache expire
  403. $this->alerts .= '<!-- DarkVoid saved: ' . curdatetime() . ' -->';
  404. //saving per-admin cache data
  405. file_put_contents(self::CACHE_PATH . self::CACHE_PREFIX . $this->myLogin, $this->alerts);
  406. }
  407. /**
  408. * Returns raw alerts data
  409. *
  410. * @return string
  411. */
  412. public function render() {
  413. $result = $this->alerts;
  414. $result .= $this->dynamicArea;
  415. return ($result);
  416. }
  417. /**
  418. * Flushes all users alert cache
  419. *
  420. * @return void
  421. */
  422. public function flushCache() {
  423. $allCache = rcms_scandir(self::CACHE_PATH, self::CACHE_PREFIX . '*', 'file');
  424. if (!empty($allCache)) {
  425. foreach ($allCache as $io => $each) {
  426. @unlink(self::CACHE_PATH . $each);
  427. }
  428. }
  429. }
  430. }