api.pononumap.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. <?php
  2. /**
  3. * Performs rendering of exiting user-assigned PON ONU devices on coverage map
  4. */
  5. class PONONUMap {
  6. /**
  7. * Contains ymaps config as key=>value
  8. *
  9. * @var array
  10. */
  11. protected $mapsCfg = array();
  12. /**
  13. * Contains alter config as key=>value
  14. *
  15. * @var array
  16. */
  17. protected $altCfg = array();
  18. /**
  19. * Contains all available users data as login=>userdata
  20. *
  21. * @var array
  22. */
  23. protected $allUserData = array();
  24. /**
  25. * PONizer object placeholder
  26. *
  27. * @var object
  28. */
  29. protected $ponizer = '';
  30. /**
  31. * System message helper object placeholder
  32. *
  33. * @var object
  34. */
  35. protected $messages = '';
  36. /**
  37. * Contains optional OLT filter
  38. *
  39. * @var int
  40. */
  41. protected $filterOltId = '';
  42. /**
  43. * Contains optional offline onu dereg reason filter substring.
  44. * Only offline ONUs will be rendered if set.
  45. *
  46. * @var string
  47. */
  48. protected $onuDeregFilter = '';
  49. /**
  50. * Contains optional onu signal filter substring
  51. *
  52. * @var string
  53. */
  54. protected $onuSignalFilter = '';
  55. /**
  56. * Concatenate builds with similar geo coordinates?
  57. *
  58. * @var bool
  59. */
  60. protected $clusterBuilds = false;
  61. /**
  62. * Predefined routes, URLs etc.
  63. */
  64. const URL_ME = '?module=ponmap';
  65. const ROUTE_FILTER_OLT = 'oltidfilter';
  66. const ROUTE_FILTER_DEREG = 'deregfilter';
  67. const ROUTE_FILTER_SIGNAL = 'signalfilter';
  68. const PROUTE_OLTSELECTOR = 'renderoltidonus';
  69. const ROUTE_BACKLINK = 'bl';
  70. const ROUTE_CLUSTER_BUILDS = 'showbuilds';
  71. /**
  72. * Creates new ONU MAP instance
  73. *
  74. * @return void
  75. */
  76. public function __construct($oltId = '') {
  77. $this->loadConfigs();
  78. $this->setBuildsClusterer();
  79. $this->setOltIdFilter($oltId);
  80. $this->setOnuDeregFilter();
  81. $this->setOnuSignalFilter();
  82. $this->initMessages();
  83. $this->initPonizer();
  84. $this->loadUsers();
  85. }
  86. /**
  87. * Sets current instance OLT filter
  88. *
  89. * @param int $oltId
  90. *
  91. * @return void
  92. */
  93. protected function setOltIdFilter($oltId = '') {
  94. if (!empty($oltId)) {
  95. $this->filterOltId = $oltId;
  96. }
  97. }
  98. /**
  99. * Sets optional ONU signal filter.
  100. *
  101. * @return void
  102. */
  103. protected function setOnuSignalFilter() {
  104. if (ubRouting::checkGet(self::ROUTE_FILTER_SIGNAL)) {
  105. $this->onuSignalFilter = ubRouting::get(self::ROUTE_FILTER_SIGNAL);
  106. }
  107. }
  108. /**
  109. * Sets optional ONU dereg reason filter.
  110. *
  111. * @return void
  112. */
  113. protected function setOnuDeregFilter() {
  114. if (ubRouting::checkGet(self::ROUTE_FILTER_DEREG)) {
  115. $this->onuDeregFilter = ubRouting::get(self::ROUTE_FILTER_DEREG);
  116. }
  117. }
  118. /**
  119. * Sets optional builds clustering
  120. *
  121. * @return void
  122. */
  123. protected function setBuildsClusterer() {
  124. if (ubRouting::checkGet(self::ROUTE_CLUSTER_BUILDS)) {
  125. $this->clusterBuilds = true;
  126. }
  127. }
  128. /**
  129. * Loads required config files into protected properties
  130. *
  131. * @global object $ubillingConfig
  132. *
  133. * @return void
  134. */
  135. protected function loadConfigs() {
  136. global $ubillingConfig;
  137. $this->mapsCfg = $ubillingConfig->getYmaps();
  138. $this->altCfg = $ubillingConfig->getAlter();
  139. }
  140. /**
  141. * Inits PONizer object instance
  142. *
  143. * @return void
  144. */
  145. protected function initPonizer() {
  146. $this->ponizer = new PONizer($this->filterOltId);
  147. }
  148. /**
  149. * Inits message helper object instance
  150. *
  151. * @return void
  152. */
  153. protected function initMessages() {
  154. $this->messages = new UbillingMessageHelper();
  155. }
  156. /**
  157. * Preloads available users data for further usage
  158. *
  159. * @return void
  160. */
  161. protected function loadUsers() {
  162. $this->allUserData = zb_UserGetAllDataCache();
  163. }
  164. /**
  165. * Returns MAP icon type due signal level
  166. *
  167. * @param string $onuSignal
  168. *
  169. * @return string
  170. */
  171. protected function getIcon($onuSignal) {
  172. $result = 'twirl#greenIcon';
  173. if ((($onuSignal > -27) and ($onuSignal < -25))) {
  174. $result = 'twirl#orangeIcon';
  175. }
  176. if ((($onuSignal > 0) or ($onuSignal < -27))) {
  177. $result = 'twirl#redIcon';
  178. }
  179. if ($onuSignal == 'NO' or $onuSignal == 'Offline' or $onuSignal == '-9000') {
  180. $result = 'twirl#greyIcon';
  181. }
  182. return ($result);
  183. }
  184. /**
  185. * Returns ONU controls
  186. *
  187. * @param int $onuId
  188. * @param string $login
  189. * @param string $buildGeo
  190. *
  191. * @return string
  192. */
  193. protected function getONUControls($onuId, $login, $buildGeo) {
  194. $result = '';
  195. if (!empty($onuId)) {
  196. $result .= wf_Link(PONizer::URL_ME . '&editonu=' . $onuId, wf_img('skins/switch_models.png', __('Edit') . ' ' . __('ONU')));
  197. $result = trim($result) . wf_nbsp();
  198. $result .= wf_Link('?module=userprofile&username=' . $login, wf_img('skins/icons/userprofile.png', __('User profile')));
  199. $result = trim($result) . wf_nbsp();
  200. $result .= wf_Link('?module=usersmap&findbuild=' . $buildGeo, wf_img('skins/icon_build.gif', __('Build')));
  201. $result = trim($result) . wf_nbsp();
  202. }
  203. return ($result);
  204. }
  205. /**
  206. * Renders module controls
  207. *
  208. * @return string
  209. */
  210. protected function renderControls() {
  211. $result = '';
  212. if (ubRouting::get(self::ROUTE_BACKLINK) == 'ponizer') {
  213. $result .= wf_BackLink(PONizer::URL_ONULIST) . ' ';
  214. } else {
  215. $result .= wf_BackLink(UbillingTaskbar::URL_ME);
  216. }
  217. if ($this->filterOltId) {
  218. $result .= wf_Link(self::URL_ME, wf_img('skins/ponmap_icon.png') . ' ' . __('All') . ' ' . __('OLT'), false, 'ubButton');
  219. } else {
  220. $result .= wf_Link(self::URL_ME, wf_img('skins/ponmap_icon.png') . ' ' . __('All') . ' ' . __('ONU'), false, 'ubButton');
  221. $result .= wf_Link(self::URL_ME . '&' . self::ROUTE_FILTER_DEREG . '=Power', wf_img('skins/icon_poweroutage.png') . ' ' . __('Power outages') . '?', false, 'ubButton');
  222. $result .= wf_Link(self::URL_ME . '&' . self::ROUTE_FILTER_DEREG . '=Wire', wf_img('skins/icon_cable.png') . ' ' . __('Wire issues') . '?', false, 'ubButton');
  223. $result .= wf_Link(self::URL_ME . '&' . self::ROUTE_FILTER_SIGNAL . '=Bad', wf_img('skins/icon_signallow.png') . ' ' . __('Bad signal'), false, 'ubButton');
  224. if ($this->clusterBuilds) {
  225. $result .= wf_Link(self::URL_ME, wf_img('skins/switch_models.png') . ' ' . __('ONU'), false, 'ubButton');
  226. } else {
  227. $result .= wf_Link(self::URL_ME . '&' . self::ROUTE_CLUSTER_BUILDS . '=true', web_build_icon() . ' ' . __('Builds'), false, 'ubButton');
  228. }
  229. }
  230. $allOlts = array('' => __('All') . ' ' . __('OLT'));
  231. $allOlts += $this->ponizer->getAllOltDevices();
  232. $result .= wf_delimiter();
  233. $opts = 'style="float:left;"';
  234. if ($this->altCfg['OLTSEL_SEARCHBL']) {
  235. $inputs = wf_SelectorSearchableAC(self::PROUTE_OLTSELECTOR, $allOlts, __('OLT'), $this->filterOltId, false);
  236. } else {
  237. $inputs = wf_SelectorAC(self::PROUTE_OLTSELECTOR, $allOlts, __('OLT'), $this->filterOltId, false);
  238. }
  239. $result .= wf_Form('', 'POST', $inputs, 'glamour', '', '', '', $opts);
  240. $result .= wf_delimiter(0);
  241. return ($result);
  242. }
  243. //
  244. // .,,.
  245. // ,KMKkkkkkkkklll. .. .. .,,,.
  246. // .lkKKl,,,,,,,lkkKMKkKkll. .. ..,l,lKKkkkkkkkKMMKl.
  247. // .lKKl. .,,lkkKMKkKk,. ,l. ,l. ,l. .kKKKkkl,,,,,,,,,lkKMKkl.
  248. // .,kMk. .,,,,,. .,,lkKMKkKMKkkKMklKMKkKKl,. .,,,. .,kMKl.
  249. // .kMk. .,lkKMKkkl. ...,lKMMk,llkMMklKKl. .... .lkKKl,. .kMl
  250. // .kMl .,,lKMKkl. .. lKl. .ll. .ll. .. ,lkKKklKMKl. lmk.
  251. //.kMk. .lKMMKllKKkKKKl .kMKKMMMMMl.. lmk.
  252. // ,KK, .KMKKKKklkKl.. ,l..,lKKKKKx,l, ,KKl.
  253. //.lKK, ..,,lMK,.... .. ..lKkKMMl .. lMKl.
  254. // lMl ..lKKKKMK, .. lKKKlkl .kMk.
  255. //.kMl lKKKKMk,. ...lKMK, lMk.
  256. // lMk. ,lkMk.,l. ,lkl,KK,
  257. // ,KMl .kkll, .,. .. ..,Kk,.
  258. // .kMk. lMl .lkkkkkkkl,,. ,KMl lk, .lkkkkKMMK,
  259. // ,KMl ,l. .lklkMk,,,lKMKkl,lKMMl lMKl,,lkkkl,,kMMMMk.
  260. // lMK. lMl .,lkkKMKl,. .lKMMKkl. .kMKKMK,
  261. // ,KMKl. lMk. .kMl ,KMk. .,lKKl.,KMk.
  262. // .,lKKkl. ,KMKl,,,,,lKKl. .lkkkkkkkkkl. ,KMKkkKKkl. lMK,
  263. // ,KMKk,. .lkkkkkkkkl. lMMMMMMMMMMMl .,,,,,. ,KMk.
  264. // .lKMMK, .kMMMMMMMMMMl lMMl
  265. // .lkKMk..l, .ll,. .lKMMMMMMkl. .,ll. lMK.
  266. // .,,lKKl.lMKkl. ,KK, .,lKMKl. ,KK, lMK,
  267. // .lKMMk,..,,,,. lMl .kMl lMl ,KMMK,
  268. // ,KMMK. ,Kl lMl .,,,,,lkKMMKkl,,. lMl lMKkl.
  269. // .kMkl. ,KK, lMl .kMMMMKKMMMMKKMMKl. ,KMl lMKl.
  270. // .lkKKkkl.lMKkkl. ,KKl. .lkKMkkMKKMkkMk,. .lKMk. .kMMl
  271. // .lKMMl.,,,,. .. ,KMKkl. .lKKl..lKKl. .kKkl. ,kKMK,
  272. // .kMMKk, .kl.,,. .,,lkl. .. .. .. .. .ll. .,,kMMk.
  273. // .lKMMMKl,,,.lMKKKl. lKl. .lKl lMKKMK,
  274. // .kMMKkkkkkKMl.lkk, .kMKl,. .,lKKl. .lkKMl.,.
  275. // .lKMMk. lMKkKMMKk.,, .lkKMKkkkkkKMKl. ,k,lKKMK,
  276. // ,KKl. .. .,,,,kMKl.lK, .,,. .,,,,,,,,,. ,;,lkKMKk,.,.
  277. // .lKMk. .kl.l, .,. lMKkKKKklkk,.,,,,. .,kMMKKMk,.
  278. // .lKMK,.kMKkk, ,kl,,.lMKlkKKKkKMK,.,,lllllkkkkkKKll,lMl
  279. // .lKMk..,,,. .,. lKl. .ll.lKKMKkl,lKKl... .kMKl.
  280. // .lKMk. ,l. .. .. ...l, .. ,KMKl,.
  281. // ,KMKl. .. lMklKl lMMk.
  282. // .lKMkl. lk.,l. .lx, ,kMKl.
  283. // .lKk. lMKKMl lKKl
  284. //
  285. //
  286. //
  287. //
  288. // ,d ,d
  289. // 88 88
  290. // ,adPPYba, MM88MMM ,adPPYba, ,adPPYYba, MM88MMM
  291. // I8[ "" 88 a8" "8a "" `Y8 88
  292. // `"Y8ba, 88 8b d8 ,adPPPPP88 88
  293. // aa ]8I 88, "8a, ,a8" 88, ,88 88,
  294. // `"YbbdP"' "Y888 `"YbbdP"' `"8bbdP"Y8 "Y888
  295. //
  296. /**
  297. * Returns a list of placemarks to render
  298. *
  299. * @param array $geoArray
  300. * @param bool $buildsClusterer
  301. *
  302. * @return string
  303. */
  304. protected function getPlacemarks($geoArray, $buildsClusterer = false) {
  305. $result = '';
  306. if (!empty($geoArray)) {
  307. foreach ($geoArray as $eachGeo => $geoData) {
  308. if (!empty($geoData)) {
  309. if ($buildsClusterer) {
  310. $buildUserCount = sizeof($geoData);
  311. if ($buildUserCount > 1) {
  312. $concatBuildContent = '';
  313. $rows = '';
  314. $cells = wf_TableCell(__('apt.'));
  315. $cells .= wf_TableCell(__('User'));
  316. $cells .= wf_TableCell(__('Signal'));
  317. $cells .= wf_TableCell(__('Actions'));
  318. $rows = wf_TableRow($cells, 'row1');
  319. foreach ($geoData as $io => $eachBuild) {
  320. $userLink = wf_Link(UserProfile::URL_PROFILE . $eachBuild['login'], $eachBuild['ip']);
  321. $cells = wf_TableCell($eachBuild['apt']);
  322. $cells .= wf_TableCell($userLink);
  323. $cells .= wf_TableCell($eachBuild['signal']);
  324. $cells .= wf_TableCell($eachBuild['controls']);
  325. $rows .= wf_TableRow($cells);
  326. }
  327. $concatBuildContent .= wf_TableBody($rows, '100%', 0, '');
  328. $concatBuildContent = str_replace("\n", '', $concatBuildContent);
  329. $result .= generic_mapAddMark($eachBuild['geo'], $eachBuild['streetbuild'], $concatBuildContent, '', 'twirl#buildingsIcon', '', true);
  330. } else {
  331. $eachBuild = $geoData[0]; //just first element as is
  332. $result .= generic_mapAddMark($eachBuild['geo'], $eachBuild['buildtitle'], $eachBuild['signal'], $eachBuild['controls'], $eachBuild['icon'], '', true);
  333. }
  334. } else {
  335. foreach ($geoData as $io => $eachBuild) {
  336. $result .= generic_mapAddMark($eachBuild['geo'], $eachBuild['buildtitle'], $eachBuild['signal'], $eachBuild['controls'], $eachBuild['icon'], '', true);
  337. }
  338. }
  339. }
  340. }
  341. }
  342. return ($result);
  343. }
  344. /**
  345. * Renders ONU signals Map
  346. *
  347. * @return string
  348. */
  349. public function renderOnuMap() {
  350. $result = '';
  351. $allOnu = $this->ponizer->getAllOnu();
  352. $allOnuSignals = $this->ponizer->getAllONUSignals();
  353. $allDeregReasons = $this->ponizer->getAllONUDeregReasons();
  354. $placemarks = '';
  355. $marksRendered = 0;
  356. $marksNoGeo = 0;
  357. $marksNoUser = 0;
  358. $marksDeadUser = 0;
  359. $totalOnuCount = 0;
  360. $result .= $this->renderControls();
  361. $renderBuilds = array();
  362. $result .= generic_MapContainer('', '', 'ponmap');
  363. if (!empty($allOnu)) {
  364. foreach ($allOnu as $io => $eachOnu) {
  365. if (!empty($eachOnu['login'])) {
  366. if (isset($this->allUserData[$eachOnu['login']])) {
  367. $userData = $this->allUserData[$eachOnu['login']];
  368. if (!empty($userData['geo'])) {
  369. if ($this->onuDeregFilter or $this->onuSignalFilter) {
  370. $renderAllowedFlag = false;
  371. } else {
  372. $renderAllowedFlag = true;
  373. }
  374. $onuSignal = (isset($allOnuSignals[$eachOnu['login']])) ? $allOnuSignals[$eachOnu['login']] : 'NO';
  375. $onuIcon = $this->getIcon($onuSignal);
  376. $onuControls = $this->getONUControls($eachOnu['id'], $eachOnu['login'], $userData['geo']);
  377. $onuTitle = $userData['fulladress'];
  378. $deregState = '';
  379. if ($onuSignal == 'NO' or $onuSignal == 'Offline' or $onuSignal == '-9000') {
  380. $signalLabel = __('No signal');
  381. if (isset($allDeregReasons[$eachOnu['login']])) {
  382. $deregLabel = $allDeregReasons[$eachOnu['login']]['styled'];
  383. $deregState = $allDeregReasons[$eachOnu['login']]['raw'];
  384. $signalLabel .= ' - ' . $deregLabel;
  385. if ($this->onuDeregFilter) {
  386. if (ispos($deregState, $this->onuDeregFilter)) {
  387. $renderAllowedFlag = true;
  388. }
  389. }
  390. }
  391. } else {
  392. $signalLabel = $onuSignal;
  393. if ($this->onuSignalFilter) {
  394. $renderAllowedFlag = false;
  395. if ($onuSignal != 'NO') {
  396. if ($onuSignal < -27) {
  397. $renderAllowedFlag = true;
  398. }
  399. }
  400. }
  401. }
  402. //48.470554, 24.422853
  403. if ($renderAllowedFlag) {
  404. $renderBuilds[$userData['geo']][] = array(
  405. 'geo' => $userData['geo'],
  406. 'streetbuild' => $userData['streetname'] . ' ' . $userData['buildnum'],
  407. 'apt' => $userData['apt'],
  408. 'buildtitle' => $onuTitle,
  409. 'login' => $userData['login'],
  410. 'ip' => $userData['ip'],
  411. 'signal' => $signalLabel,
  412. 'controls' => $onuControls,
  413. 'icon' => $onuIcon,
  414. );
  415. $marksRendered++;
  416. }
  417. } else {
  418. $marksNoGeo++;
  419. }
  420. } else {
  421. if ($eachOnu['login'] != 'dead') {
  422. $marksNoUser++;
  423. } else {
  424. $marksDeadUser++;
  425. }
  426. }
  427. } else {
  428. $marksNoUser++;
  429. }
  430. $totalOnuCount++;
  431. }
  432. $placemarks .= $this->getPlacemarks($renderBuilds, $this->clusterBuilds);
  433. }
  434. //rendering map
  435. $result .= generic_MapInit($this->mapsCfg['CENTER'], $this->mapsCfg['ZOOM'], $this->mapsCfg['TYPE'], $placemarks, '', $this->mapsCfg['LANG'], 'ponmap');
  436. //some stats here
  437. $result .= $this->messages->getStyledMessage(__('Total') . ' ' . __('ONU') . ': ' . $totalOnuCount, 'info');
  438. $result .= $this->messages->getStyledMessage(__('ONU rendered on map') . ': ' . $marksRendered, 'success');
  439. if ($marksNoGeo > 0) {
  440. $result .= $this->messages->getStyledMessage(__('User builds not placed on map') . ': ' . $marksNoGeo, 'warning');
  441. }
  442. if ($marksNoUser > 0) {
  443. $result .= $this->messages->getStyledMessage(__('ONU without assigned user') . ': ' . $marksNoUser, 'warning');
  444. }
  445. return ($result);
  446. }
  447. /**
  448. * Returns label if rendering ONUs for only some specified OLT
  449. *
  450. * @return string
  451. */
  452. public function getFilteredOLTLabel() {
  453. $result = '';
  454. $onuFilterLabel = '';
  455. if ($this->filterOltId) {
  456. $allOltDevices = $this->ponizer->getAllOltDevices();
  457. if (isset($allOltDevices[$this->filterOltId])) {
  458. $result .= ': ' . $allOltDevices[$this->filterOltId];
  459. }
  460. }
  461. if ($this->onuDeregFilter) {
  462. switch ($this->onuDeregFilter) {
  463. case 'Power':
  464. $onuFilterLabel .= __('Power outages') . '?';
  465. break;
  466. case 'Wire':
  467. $onuFilterLabel .= __('Wire issues') . '?';
  468. break;
  469. }
  470. $result .= ' : ' . $onuFilterLabel;
  471. }
  472. if ($this->onuSignalFilter) {
  473. switch ($this->onuSignalFilter) {
  474. case 'Bad':
  475. $onuFilterLabel .= __('Bad signal');
  476. break;
  477. }
  478. $result .= ' : ' . $onuFilterLabel;
  479. }
  480. return ($result);
  481. }
  482. }