api.ponboxes.php 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049
  1. <?php
  2. /**
  3. * PON Boxes allows to place/render some boxes on map
  4. */
  5. class PONBoxes {
  6. /**
  7. * Contains system alter config as key=>value
  8. *
  9. * @var array
  10. */
  11. protected $altCfg = array();
  12. /**
  13. * Contains all available PON boxes as boxid=>boxdata
  14. *
  15. * @var array
  16. */
  17. protected $allBoxes = array();
  18. /**
  19. * Contains all available user/address/onu links to boxes as linkid=>boxid
  20. *
  21. * @var array
  22. */
  23. protected $allLinks = array();
  24. /**
  25. * Contains all available ponboxes splitters links as linkid=>boxid
  26. *
  27. * @var array
  28. */
  29. protected $allSplittersLinks = array();
  30. /**
  31. * Database abstraction layer with ponboxes
  32. *
  33. * @var object
  34. */
  35. protected $boxes = '';
  36. /**
  37. * Database abstraction layer with ponboxes links to users/addresses/ONUs etc
  38. *
  39. * @var object
  40. */
  41. protected $links = '';
  42. /**
  43. * Database abstraction layer with ponboxes splitters links
  44. *
  45. * @var object
  46. */
  47. protected $splittersLinks = '';
  48. /**
  49. * System message helper object placeholder
  50. *
  51. * @var object
  52. */
  53. protected $messages = '';
  54. /**
  55. * System image storage placeholder
  56. *
  57. * @var object
  58. */
  59. protected $photoStorage = null;
  60. /**
  61. * Pre-defined list pf splitters and couplers
  62. *
  63. * @var string[]
  64. */
  65. protected $splittersTypesList = array();
  66. /**
  67. * Contains preloaded users address array
  68. *
  69. * @var array
  70. */
  71. protected $allUserAddress = array();
  72. /**
  73. * Routes, static defines etc
  74. */
  75. const URL_ME = '?module=ponboxes';
  76. const PROUTE_NEWBOXNAME = 'newboxname';
  77. const PROUTE_NEWBOEXTENINFO = 'newboxexteninfo';
  78. const PROUTE_NEWBOXGEO = 'newboxgeo';
  79. const PROUTE_NEWLINKBOX = 'newlinkboxid';
  80. const PROUTE_NEWLINKTYPE = 'newlinktype';
  81. const PROUTE_NEWLINKONU = 'newlinkonu';
  82. const PROUTE_MAPBOXID = 'setboxidonmap';
  83. const PROUTE_MAPBOXCOORDS = 'newboxmapcoords';
  84. const ROUTE_BOXLIST = 'ajboxes';
  85. const ROUTE_BOXNAV = 'boxidnav';
  86. const ROUTE_MAP = 'boxmap';
  87. const ROUTE_BOXEDIT = 'editboxid';
  88. const ROUTE_BOXDEL = 'deleteboxid';
  89. const ROUTE_LINKDEL = 'deletelinkid';
  90. const ROUTE_SPLITTERADD = 'addboxsplitters';
  91. const ROUTE_SPLITTERDEL = 'delboxsplitters';
  92. const ROUTE_PLACEBOX = 'plcmapboxid';
  93. const TABLE_BOXES = 'ponboxes';
  94. const TABLE_LINKS = 'ponboxeslinks';
  95. const TABLE_SPLITTERSLINKS = 'ponboxes_splitters';
  96. const TABLE_PONONU = 'pononu';
  97. const PHOTOSTORAGE_SCOPE = 'PONBOXES';
  98. /**
  99. * Creates new PONBoxes instance
  100. *
  101. * @param bool $loadFullData
  102. *
  103. * @return void
  104. */
  105. public function __construct($loadFullData = false) {
  106. $this->initMessages();
  107. $this->loadConfigs();
  108. $this->setSplitterTypes();
  109. $this->initDatabase();
  110. if ($loadFullData) {
  111. $this->loadAllAddress();
  112. $this->loadBoxes();
  113. $this->loadLinks();
  114. $this->loadSplittersLinks();
  115. }
  116. }
  117. /**
  118. * Inits system message helper instance
  119. *
  120. * @return void
  121. */
  122. protected function initMessages() {
  123. $this->messages = new UbillingMessageHelper();
  124. }
  125. /**
  126. * Inits system image storage placeholder
  127. *
  128. * @return void
  129. */
  130. protected function initPhotoStorage() {
  131. $this->photoStorage = new PhotoStorage('PONBOXES');
  132. }
  133. /**
  134. * Loads some required configs
  135. *
  136. * @global object $ubillingConfig
  137. *
  138. * @return void
  139. */
  140. protected function loadConfigs() {
  141. global $ubillingConfig;
  142. $this->altCfg = $ubillingConfig->getAlter();
  143. }
  144. /**
  145. * Loads all users address data into protected property
  146. *
  147. * @return void
  148. */
  149. protected function loadAllAddress() {
  150. $this->allUserAddress = zb_AddressGetFulladdresslistCached();
  151. }
  152. /**
  153. * Sets predefined splitters ad couplers list
  154. *
  155. * @return void
  156. */
  157. protected function setSplitterTypes() {
  158. $this->splittersTypesList = array(
  159. 'Coupler 5:95' => __('Coupler') . ' 5:95',
  160. 'Coupler 10:90' => __('Coupler') . ' 10:90',
  161. 'Coupler 15:85' => __('Coupler') . ' 15:85',
  162. 'Coupler 20:80' => __('Coupler') . ' 20:80',
  163. 'Coupler 25:75' => __('Coupler') . ' 25:75',
  164. 'Coupler 30:70' => __('Coupler') . ' 30:70',
  165. 'Coupler 35:65' => __('Coupler') . ' 35:65',
  166. 'Coupler 40:60' => __('Coupler') . ' 40:60',
  167. 'Coupler 45:55' => __('Coupler') . ' 45:55',
  168. 'Coupler 50:50' => __('Coupler') . ' 50:50',
  169. 'Splitter 1 x 2' => __('Splitter') . ' 1 x 2',
  170. 'Splitter 1 x 3' => __('Splitter') . ' 1 x 3',
  171. 'Splitter 1 x 4' => __('Splitter') . ' 1 x 4',
  172. 'Splitter 1 x 5' => __('Splitter') . ' 1 x 5',
  173. 'Splitter 1 x 6' => __('Splitter') . ' 1 x 6',
  174. 'Splitter 1 x 8' => __('Splitter') . ' 1 x 8',
  175. 'Splitter 1 x 12' => __('Splitter') . ' 1 x 12',
  176. 'Splitter 1 x 16' => __('Splitter') . ' 1 x 16',
  177. 'Splitter 1 x 32' => __('Splitter') . ' 1 x 32',
  178. 'Splitter 1 x 64' => __('Splitter') . ' 1 x 64'
  179. );
  180. }
  181. /**
  182. * Inits all required database abstraction layers for further usage
  183. *
  184. * @return void
  185. */
  186. protected function initDatabase() {
  187. $this->boxes = new NyanORM(self::TABLE_BOXES);
  188. $this->links = new NyanORM(self::TABLE_LINKS);
  189. $this->splittersLinks = new NyanORM(self::TABLE_SPLITTERSLINKS);
  190. // . ,.
  191. // T."-._..---.._,-"/|
  192. // l|"-. _.v._ (" |
  193. // [l /.'_ \; _~"-.`-t
  194. // Y " _(o} _{o)._ ^.|
  195. // j T ,-<v>-. T ]
  196. // \ l ( /-^-\ ) ! !
  197. // \. \. "~" ./ /c-..,__
  198. // ^r- .._ .- .-" `- . ~"--.
  199. // > \. \
  200. // ] ^. \
  201. // 3 . "> . Y -MEOW! WHERE IS MY BOX?!
  202. // ,.__.--._ _j \ ~ . ; |
  203. // ( ~"-._~"^._\ ^. ^._ I . l
  204. // "-._ ___ ~"-,_7 .Z-._ 7" Y ; \ _
  205. // /" "~-(r r _/_--._~-/ / /,.--^-._ / Y
  206. // "-._ '"~~~>-._~]>--^---./____,.^~ ^.^ !
  207. // ~--._ ' Y---. \./
  208. // ~~--._ l_ ) \
  209. // ~-._~~~---._,____..--- \
  210. // ~----"~ \
  211. // \
  212. }
  213. /**
  214. * Loads all available boxes from database
  215. *
  216. * @return void
  217. */
  218. protected function loadBoxes() {
  219. if (@$this->altCfg['PONBOXES_NAME_ORDER']) {
  220. $this->boxes->orderBy('name', 'ASC');
  221. }
  222. $this->allBoxes = $this->boxes->getAll('id');
  223. }
  224. /**
  225. * Loads all available boxes to something links from database
  226. *
  227. * @return void
  228. */
  229. protected function loadLinks() {
  230. $this->allLinks = $this->links->getAll('id');
  231. }
  232. protected function loadSplittersLinks() {
  233. $this->allSplittersLinks = $this->splittersLinks->getAll('id');
  234. }
  235. /**
  236. * Renders all available boxes list container
  237. *
  238. * @return string
  239. */
  240. public function renderBoxesList() {
  241. $result = '';
  242. $columns = array('ID', 'Name', 'Additional info', 'Location', 'Actions');
  243. $opts = '"order": [[ 0, "desc" ]]';
  244. $result .= wf_JqDtLoader($columns, self::URL_ME . '&' . self::ROUTE_BOXLIST . '=true', false, __('boxes'), 100, $opts);
  245. return ($result);
  246. }
  247. /**
  248. * Renders JSON data with all available PON boxes list and some controls
  249. *
  250. * @return void
  251. */
  252. public function ajBoxesList() {
  253. $json = new wf_JqDtHelper();
  254. if (!empty($this->allBoxes)) {
  255. foreach ($this->allBoxes as $io => $each) {
  256. $data[] = $each['id'];
  257. $data[] = $each['name'];
  258. $data[] = $each['exten_info'];
  259. $data[] = $each['geo'];
  260. $boxActs = '';
  261. $boxActs .= wf_Link(self::URL_ME . '&' . self::ROUTE_BOXEDIT . '=' . $each['id'], web_edit_icon());
  262. $data[] = $boxActs;
  263. $json->addRow($data);
  264. unset($data);
  265. }
  266. }
  267. $json->getJson();
  268. }
  269. /**
  270. * Renders new pon box creation form. Its obvious.
  271. *
  272. * @return string
  273. */
  274. protected function renderBoxCreateForm() {
  275. $result = '';
  276. $sup = wf_tag('sup') . '*' . wf_tag('sup', true);
  277. $inputs = wf_TextInput('newboxname', __('Name') . $sup, '', true, 20);
  278. $inputs .= wf_TextInput('newboxexteninfo', __('Additional info'), '', true, 20);
  279. $inputs .= wf_TextInput('newboxgeo', __('Location'), '', true, 20, 'geo');
  280. $inputs .= wf_Submit(__('Create'));
  281. $result .= wf_Form('', 'POST', $inputs, 'glamour');
  282. return ($result);
  283. }
  284. /**
  285. * Renders existing box editing form aka "Box profile"
  286. *
  287. * @param int $boxId
  288. *
  289. * @return string
  290. */
  291. public function renderBoxEditForm($boxId) {
  292. $boxId = ubRouting::filters($boxId, 'int');
  293. $result = '';
  294. if (isset($this->allBoxes[$boxId])) {
  295. $boxData = $this->allBoxes[$boxId];
  296. $sup = wf_tag('sup') . '*' . wf_tag('sup', true);
  297. $inputs = wf_HiddenInput('editboxid', $boxId);
  298. $inputs .= wf_TextInput('editboxname', __('Name') . $sup, $boxData['name'], true, 20);
  299. $inputs .= wf_TextInput('editboxexteninfo', __('Additional info'), $boxData['exten_info'], true, 20);
  300. $inputs .= wf_TextInput('editboxgeo', __('Location'), $boxData['geo'], true, 20, 'geo');
  301. $inputs .= wf_Submit(__('Save'));
  302. $result .= wf_Form('', 'POST', $inputs, 'glamour');
  303. $result .= wf_delimiter(0);
  304. $result .= wf_BackLink(self::URL_ME);
  305. if (!$this->isBoxProtected($boxId)) {
  306. $boxDelControlUrl = self::URL_ME . '&' . self::ROUTE_BOXDEL . '=' . $boxId;
  307. $boxDelCancelUrl = self::URL_ME . '&' . self::ROUTE_BOXEDIT . '=' . $boxId;
  308. $result .= wf_ConfirmDialogJS($boxDelControlUrl, web_delete_icon() . ' ' . __('Delete'), $this->messages->getDeleteAlert(), 'ubButton', $boxDelCancelUrl) . ' ';
  309. }
  310. if (empty($boxData['geo'])) {
  311. $mapPlaceUrl = self::URL_ME . '&' . self::ROUTE_MAP . '=true&' . self::ROUTE_PLACEBOX . '=' . $boxId;
  312. $result .= wf_Link($mapPlaceUrl, wf_img('skins/ymaps/target.png') . ' ' . __('Place on map'), false, 'ubButton');
  313. }
  314. } else {
  315. $result .= $this->messages->getStyledMessage(__('Something went wrong') . ': ' . __('box') . ' [' . $boxId . '] ' . __('Not exists'), 'error');
  316. }
  317. return ($result);
  318. }
  319. /**
  320. * Saves box data if required
  321. *
  322. * @return void/string on error
  323. */
  324. public function saveBox() {
  325. $result = '';
  326. if (ubRouting::checkPost(array('editboxid', 'editboxname'))) {
  327. $boxId = ubRouting::post('editboxid', 'int');
  328. $newBoxName = ubRouting::post('editboxname');
  329. $newBoxNameF = ubRouting::filters($newBoxName, 'mres');
  330. $newBoxExtenInfo = ubRouting::post('editboxexteninfo');
  331. $newBoxExtenInfoF = ubRouting::filters($newBoxExtenInfo, 'mres');
  332. $newBoxGeoF = ubRouting::post('editboxgeo', 'mres');
  333. if (isset($this->allBoxes[$boxId])) {
  334. $boxData = $this->allBoxes[$boxId];
  335. if ($newBoxNameF != $boxData['name']) {
  336. //name changed
  337. if ($this->isBoxNameFree($newBoxNameF)) {
  338. //and still is unique
  339. $this->boxes->data('name', $newBoxNameF);
  340. $this->boxes->where('id', '=', $boxId);
  341. $this->boxes->save();
  342. log_register('PONBOX CHANGE BOX [' . $boxId . '] NAME `' . $newBoxName . '`');
  343. } else {
  344. $result .= __('This box already exists');
  345. }
  346. }
  347. if ($newBoxExtenInfoF != $boxData['exten_info']) {
  348. $this->boxes->data('exten_info', $newBoxExtenInfoF);
  349. $this->boxes->where('id', '=', $boxId);
  350. $this->boxes->save();
  351. log_register('PONBOX CHANGE BOX [' . $boxId . '] EXTEN INFO');
  352. }
  353. if ($newBoxGeoF != $boxData['geo']) {
  354. $this->boxes->data('geo', $newBoxGeoF);
  355. $this->boxes->where('id', '=', $boxId);
  356. $this->boxes->save();
  357. log_register('PONBOX CHANGE BOX [' . $boxId . '] GEO `' . $newBoxGeoF . '`');
  358. }
  359. } else {
  360. $result .= __('Something went wrong') . ': ' . __('box') . ' [' . $boxId . '] ' . __('Not exists');
  361. }
  362. }
  363. return ($result);
  364. }
  365. /**
  366. * Check is box name already used or not?
  367. *
  368. * @param string $boxName
  369. *
  370. * @return bool
  371. */
  372. protected function isBoxNameFree($boxName) {
  373. $result = true;
  374. if (!empty($this->allBoxes)) {
  375. foreach ($this->allBoxes as $io => $each) {
  376. if ($each['name'] == $boxName) {
  377. $result = false;
  378. break;
  379. }
  380. }
  381. }
  382. return ($result);
  383. }
  384. /**
  385. * Creates new PON box in database
  386. *
  387. * @param string $name
  388. * @param string $geo
  389. *
  390. * @return void/string on error
  391. */
  392. public function createBox($name, $extenInfo = '', $geo = '') {
  393. $result = '';
  394. $nameF = ubRouting::filters($name, 'mres');
  395. $extenInfoF = ubRouting::filters($extenInfo, 'mres');
  396. $geoF = ubRouting::filters($geo, 'mres');
  397. if (!empty($nameF)) {
  398. if ($this->isBoxNameFree($nameF)) {
  399. $this->boxes->data('name', $nameF);
  400. $this->boxes->data('exten_info', $extenInfoF);
  401. $this->boxes->data('geo', $geoF);
  402. $this->boxes->create();
  403. $newId = $this->boxes->getLastId();
  404. log_register('PONBOX CREATE BOX [' . $newId . '] NAME `' . $name . '`');
  405. } else {
  406. $result .= __('This box already exists');
  407. }
  408. } else {
  409. $result .= __('All fields marked with an asterisk are mandatory');
  410. }
  411. return ($result);
  412. }
  413. /**
  414. * Renders default controls panel
  415. *
  416. * @return string
  417. */
  418. public function renderControls() {
  419. $result = '';
  420. $result .= wf_modalAuto(web_icon_create() . ' ' . __('Create'), __('Create'), $this->renderBoxCreateForm(), 'ubButton') . ' ';
  421. if (ubRouting::checkGet(self::ROUTE_MAP) or ubRouting::checkGet(self::ROUTE_BOXEDIT)) {
  422. $result .= wf_Link(self::URL_ME, wf_img('skins/icon_table.png') . ' ' . __('List'), false, 'ubButton');
  423. } else {
  424. $result .= wf_Link(self::URL_ME . '&' . self::ROUTE_MAP . '=true', wf_img('skins/ponmap_icon.png') . ' ' . __('Map'), false, 'ubButton');
  425. }
  426. return ($result);
  427. }
  428. /**
  429. * Check is box protected wit some existing links
  430. *
  431. * @param int $boxId
  432. *
  433. * @return bool
  434. */
  435. protected function isBoxProtected($boxId) {
  436. $boxId = ubRouting::filters($boxId, 'int');
  437. $result = false;
  438. if (!empty($this->allLinks)) {
  439. foreach ($this->allLinks as $io => $each) {
  440. if ($each['boxid'] == $boxId) {
  441. $result = true;
  442. break;
  443. }
  444. }
  445. }
  446. return ($result);
  447. }
  448. /**
  449. * Deletes existing PON box from database
  450. *
  451. * @param int $boxId
  452. *
  453. * @return void/string on error
  454. */
  455. public function deleteBox($boxId) {
  456. $boxId = ubRouting::filters($boxId, 'int');
  457. $result = '';
  458. if (isset($this->allBoxes[$boxId])) {
  459. if (!$this->isBoxProtected($boxId)) {
  460. $boxData = $this->allBoxes[$boxId];
  461. $this->boxes->where('id', '=', $boxId);
  462. $this->boxes->delete();
  463. log_register('PONBOX DELETE BOX [' . $boxId . '] NAME `' . $boxData['name'] . '`');
  464. } else {
  465. $result .= __('Something went wrong') . ': ' . __('This item is used by something');
  466. }
  467. } else {
  468. $result .= __('Something went wrong') . ': ' . __('box') . ' [' . $boxId . '] ' . __('Not exists');
  469. }
  470. return ($result);
  471. }
  472. /**
  473. * Delete link from database
  474. *
  475. * @param int $linkId
  476. * @param bool $deleteSplitter
  477. *
  478. * @return void/string on error
  479. */
  480. public function deleteLink($linkId, $deleteSplitter = false) {
  481. $linkId = ubRouting::filters($linkId, 'int');
  482. $result = '';
  483. if ($deleteSplitter) {
  484. if (isset($this->allSplittersLinks[$linkId])) {
  485. $linkData = $this->allSplittersLinks[$linkId];
  486. $this->splittersLinks->where('id', '=', $linkId);
  487. $this->splittersLinks->delete();
  488. log_register('PONBOX DELETE SPLITTER [' . $linkId . '] BOX [' . $linkData['boxid'] . ']');
  489. } else {
  490. $result .= __('Something went wrong') . ': ' . __('Splitter') . ' [' . $linkId . '] ' . __('Not exists');
  491. }
  492. } else {
  493. if (isset($this->allLinks[$linkId])) {
  494. $linkData = $this->allLinks[$linkId];
  495. $this->links->where('id', '=', $linkId);
  496. $this->links->delete();
  497. log_register('PONBOX DELETE LINK [' . $linkId . '] BOX [' . $linkData['boxid'] . ']');
  498. } else {
  499. $result .= __('Something went wrong') . ': ' . __('Link') . ' [' . $linkId . '] ' . __('Not exists');
  500. }
  501. }
  502. return ($result);
  503. }
  504. /**
  505. * Returns form for setting location of the box on map
  506. *
  507. * @param int $boxId
  508. *
  509. * @return string
  510. */
  511. protected function getBoxPlaceForm($boxId) {
  512. $result = '';
  513. $boxId = ubRouting::filters($boxId, 'int');
  514. $boxData = $this->allBoxes[$boxId];
  515. $inputs = wf_HiddenInput(self::PROUTE_MAPBOXID, $boxId);
  516. $inputs .= wf_delimiter(1);
  517. $inputs .= __('Box') . ': ' . $boxData['name'];
  518. $inputs .= wf_delimiter(1);
  519. $inputs .= wf_Submit('Save');
  520. $result .= generic_MapEditor(self::PROUTE_MAPBOXCOORDS, __('Place on map'), $inputs);
  521. return($result);
  522. }
  523. /**
  524. * Sets some new geo coords for existing box
  525. *
  526. * @param int $boxId
  527. * @param string $coords
  528. *
  529. * @return void
  530. */
  531. public function setBoxGeo($boxId, $coords = '') {
  532. $boxId = ubRouting::filters($boxId, 'int');
  533. $coords = ubRouting::filters($coords, 'mres');
  534. $this->boxes->where('id', '=', $boxId);
  535. $this->boxes->data('geo', $coords);
  536. $this->boxes->save();
  537. log_register('PONBOX CHANGE BOX [' . $boxId . '] GEO `' . $coords . '`');
  538. }
  539. /**
  540. * Renders available boxes map
  541. *
  542. * @global object $ubillingConfig
  543. *
  544. * @return string
  545. */
  546. public function renderBoxesMap() {
  547. global $ubillingConfig;
  548. $mapsCfg = $ubillingConfig->getYmaps();
  549. $result = '';
  550. if (!empty($this->allBoxes)) {
  551. $mapContainer = 'ponboxmap';
  552. $result .= generic_MapContainer('100%', '800px', $mapContainer);
  553. $placemarks = '';
  554. $editor = '';
  555. if (ubRouting::checkGet(self::ROUTE_PLACEBOX)) {
  556. $placeBoxId = ubRouting::get(self::ROUTE_PLACEBOX, 'int');
  557. $editor .= $this->getBoxPlaceForm($placeBoxId);
  558. }
  559. foreach ($this->allBoxes as $io => $each) {
  560. if (!empty($each['geo'])) {
  561. $boxLink = trim(wf_Link(self::URL_ME . '&' . self::ROUTE_BOXEDIT . '=' . $each['id'], web_edit_icon()));
  562. $placemarks .= generic_mapAddMark($each['geo'], '', $each['name'] . ' ' . $boxLink, '', '', '', true);
  563. }
  564. }
  565. $result .= generic_MapInit($mapsCfg['CENTER'], $mapsCfg['ZOOM'], $mapsCfg['TYPE'], $placemarks, $editor, $mapsCfg['LANG'], $mapContainer);
  566. } else {
  567. $result .= $this->messages->getStyledMessage(__('Nothing to show'), 'warning');
  568. }
  569. return ($result);
  570. }
  571. /**
  572. * Creates box->entity link in database
  573. *
  574. * @param int $boxId existing PON Box ID
  575. * @param string $type link type: login, address, login+address, onuid
  576. * @param array $param link parameter
  577. *
  578. * @return void/string on error
  579. */
  580. protected function createLink($boxId, $type, $param) {
  581. $result = '';
  582. $useField = array();
  583. $boxId = ubRouting::filters($boxId, 'int');
  584. if (isset($this->allBoxes[$boxId])) {
  585. $saveLink = true;
  586. switch ($type) {
  587. case 'login':
  588. $useField = array('login');
  589. break;
  590. case 'address':
  591. $useField = array('address');
  592. break;
  593. case 'loginaddress':
  594. $useField = array('login', 'address');
  595. break;
  596. case 'onuid':
  597. $useField = array('onuid');
  598. break;
  599. default:
  600. $saveLink = false;
  601. $result .= __('Unknown link type') . ' ' . $type;
  602. break;
  603. }
  604. if ($saveLink) {
  605. $fieldsCount = count($useField);
  606. $this->links->data('boxid', $boxId);
  607. for ($i = 0; $i < $fieldsCount; $i++) {
  608. $paramF = ubRouting::filters($param[$i], 'mres');
  609. $this->links->data($useField[$i], $paramF);
  610. }
  611. $this->links->create();
  612. $newId = $this->links->getLastId();
  613. log_register('PONBOX CREATE LINK [' . $newId . '] BOX [' . $boxId . '] TYPE `' . $type . '` TO `' . implode(', ', $param) . '`');
  614. }
  615. } else {
  616. $result .= __('Something went wrong') . ': ' . __('box') . ' [' . $boxId . '] ' . __('Not exists');
  617. }
  618. return ($result);
  619. }
  620. /**
  621. * Search some linked boxes for this ONU
  622. *
  623. * @param array $onuData
  624. *
  625. * @return array
  626. */
  627. public function getLinkedBoxes($onuData) {
  628. $result = array();
  629. if (!empty($onuData)) {
  630. $onuId = $onuData['id'];
  631. $onuUser = $onuData['login'];
  632. if (!empty($this->allLinks)) {
  633. foreach ($this->allLinks as $io => $eachLink) {
  634. //ONU ID link search
  635. if ($eachLink['onuid'] == $onuId) {
  636. $result[$eachLink['boxid']] = $eachLink['boxid'];
  637. }
  638. // This is the water.
  639. // And this is the well.
  640. // Drink full and descend.
  641. // The horse is the white of the eyes and dark within.
  642. if (!empty($onuUser)) {
  643. //address search
  644. $onuUserAddress = @$this->allUserAddress[$onuUser];
  645. if ($eachLink['address'] == $onuUserAddress) {
  646. $result[$eachLink['boxid']] = $eachLink['id'];
  647. }
  648. //direct login search
  649. if ($eachLink['login'] == $onuUser) {
  650. $result[$eachLink['boxid']] = $eachLink['id'];
  651. }
  652. }
  653. }
  654. }
  655. }
  656. return ($result);
  657. }
  658. /**
  659. * Renders linked lined boxes list
  660. *
  661. * @param array $boxesArray
  662. * @param bool $userProfile
  663. *
  664. * @return string
  665. */
  666. public function renderLinkedBoxes($boxesArray, $userProfile = false) {
  667. $result = '';
  668. if (!empty($boxesArray)) {
  669. foreach ($boxesArray as $boxId => $linkId) {
  670. $boxName = $this->allBoxes[$boxId]['name'];
  671. $boxLink = wf_Link(self::URL_ME . '&' . self::ROUTE_BOXEDIT . '=' . $boxId, $boxName);
  672. if ($userProfile) {
  673. $result .= wf_tag('span', false, '', 'style="color: #32510F; font-size: 14px;"') . $boxLink . wf_delimiter(0) . wf_tag('span', true);
  674. } else {
  675. $result .= $this->messages->getStyledMessage(__('Box') . ': ' . $boxLink, 'success');
  676. }
  677. }
  678. } else {
  679. if ($userProfile) {
  680. $result .= wf_tag('span', false, '', 'style="color: #32510F"; font-size: 14px;') . __('PON Boxes') . ': ' . __('Nothing to show') . wf_tag('span', true);
  681. } else {
  682. $result .= $this->messages->getStyledMessage(__('PON Boxes') . ': ' . __('Nothing to show'), 'info');
  683. }
  684. }
  685. return ($result);
  686. }
  687. /**
  688. * Returns linked entity control link
  689. *
  690. * @param array $linkData
  691. *
  692. * @return string
  693. */
  694. protected function getLinkEntityControl($linkData) {
  695. $result = '';
  696. if (!empty($linkData)) {
  697. if (!empty($linkData['login']) and ! empty($linkData['address'])) {
  698. $result .= wf_Link('?module=userprofile&username=' . $linkData['login'], web_profile_icon() . ' ' . $linkData['login'])
  699. . wf_img('skins/icon_build.gif', __('Address')) . ' ' . $linkData['address'];
  700. } else {
  701. if (!empty($linkData['login'])) {
  702. $result .= wf_Link('?module=userprofile&username=' . $linkData['login'], web_profile_icon() . ' ' . $linkData['login']);
  703. }
  704. if (!empty($linkData['onuid'])) {
  705. $result .= wf_Link('?module=ponizer&editonu=' . $linkData['onuid'], wf_img('skins/switch_models.png', __('ONU')) . ' ' . $linkData['onuid']);
  706. }
  707. if (!empty($linkData['address'])) {
  708. $result .= wf_img('skins/icon_build.gif', __('Address')) . ' ' . $linkData['address'];
  709. }
  710. }
  711. }
  712. return ($result);
  713. }
  714. /**
  715. * Renders existing POB Box links of any type
  716. *
  717. * @param int $boxId
  718. *
  719. * @return string
  720. */
  721. public function renderBoxLinksList($boxId) {
  722. $result = '';
  723. $boxId = ubRouting::filters($boxId, 'int');
  724. if (isset($this->allBoxes[$boxId])) {
  725. if (!empty($this->allLinks)) {
  726. $curBoxLinks = array();
  727. foreach ($this->allLinks as $io => $each) {
  728. if ($each['boxid'] == $boxId) {
  729. $curBoxLinks[] = $each;
  730. }
  731. }
  732. if (!empty($curBoxLinks)) {
  733. $cells = wf_TableCell(__('User') . ' / ' . __('ONU') . ' / ' . __('Address'));
  734. $cells .= wf_TableCell(__('Actions'));
  735. $rows = wf_TableRow($cells, 'row1');
  736. foreach ($curBoxLinks as $io => $each) {
  737. $cells = wf_TableCell($this->getLinkEntityControl($each));
  738. $delLinkUrl = self::URL_ME . '&' . self::ROUTE_LINKDEL . '=' . $each['id'] . '&' . self::ROUTE_BOXNAV . '=' . $each['boxid'];
  739. $actLinks = wf_JSAlert($delLinkUrl, web_delete_icon(), $this->messages->getDeleteAlert());
  740. $cells .= wf_TableCell($actLinks);
  741. $rows .= wf_TableRow($cells, 'row5');
  742. }
  743. $result .= wf_TableBody($rows, '100%', 0, 'sortable');
  744. } else {
  745. $result .= $this->messages->getStyledMessage(__('Nothing to show'), 'info');
  746. }
  747. } else {
  748. $result .= $this->messages->getStyledMessage(__('Nothing to show'), 'warning');
  749. }
  750. } else {
  751. $result .= $this->messages->getStyledMessage(__('Something went wrong') . ': ' . __('box') . ' [' . $boxId . '] ' . __('Not exists'), 'error');
  752. }
  753. return ($result);
  754. }
  755. /**
  756. * Renders box assign form. With some ONU or another ONU params
  757. *
  758. * @param array $onuData
  759. *
  760. * @return string
  761. */
  762. public function renderBoxAssignForm($onuData) {
  763. $result = '';
  764. $boxesTmp = array('' => '-');
  765. if (!empty($onuData)) {
  766. $onuId = $onuData['id'];
  767. $onuUserName = $onuData['login'];
  768. $onuUserName = trim($onuUserName);
  769. if (!empty($this->allBoxes)) {
  770. $inputs = '';
  771. foreach ($this->allBoxes as $eachBoxId => $eachBoxData) {
  772. $boxesTmp[$eachBoxData['id']] = $eachBoxData['name'];
  773. }
  774. $inputs .= wf_HiddenInput(self::PROUTE_NEWLINKONU, $onuId);
  775. $inputs .= wf_Selector(self::PROUTE_NEWLINKBOX, $boxesTmp, __('box'), '', false, false) . ' ';
  776. $inputs .= wf_nbsp(2);
  777. if (!empty($onuUserName)) {
  778. $inputs .= wf_RadioInput(self::PROUTE_NEWLINKTYPE, __('ONU'), 'onuid', false, true) . ' ';
  779. $inputs .= wf_RadioInput(self::PROUTE_NEWLINKTYPE, __('User'), 'login', false, false) . ' ';
  780. $inputs .= wf_RadioInput(self::PROUTE_NEWLINKTYPE, __('Address'), 'address', false, false) . ' ';
  781. $inputs .= wf_RadioInput(self::PROUTE_NEWLINKTYPE, __('Login') . ' + ' . __('Address'), 'loginaddress', false, false) . ' ';
  782. } else {
  783. $inputs .= wf_HiddenInput(self::PROUTE_NEWLINKTYPE, 'onuid');
  784. }
  785. $inputs .= wf_nbsp(2);
  786. $inputs .= wf_Submit(__('Create new PON box link'));
  787. $result .= wf_Form('', 'POST', $inputs, 'glamour');
  788. }
  789. }
  790. return ($result);
  791. }
  792. /**
  793. * Create PON box link with some ONU by some type in database
  794. *
  795. * @param int $boxId
  796. * @param int $onuId
  797. * @param string $linkType
  798. *
  799. * @return void/string on error
  800. */
  801. public function createLinkONU($boxId, $onuId, $linkType) {
  802. $result = '';
  803. $boxId = ubRouting::filters($boxId, 'int');
  804. $onuId = ubRouting::filters($onuId, 'int');
  805. if (isset($this->allBoxes[$boxId])) {
  806. //PON ONU database abstraction workaround here
  807. $ponOnu = new NyanORM(self::TABLE_PONONU);
  808. $ponOnu->where('id', '=', $onuId);
  809. $onuData = $ponOnu->getAll();
  810. if (!empty($onuData)) {
  811. $onuData = $onuData[0];
  812. //trying to create link
  813. if ($linkType == 'onuid') {
  814. $result .= $this->createLink($boxId, $linkType, array($onuId));
  815. }
  816. if ($linkType == 'login' or $linkType == 'address' or $linkType == 'loginaddress') {
  817. $userLogin = trim($onuData['login']);
  818. if (!empty($userLogin)) {
  819. $userData = zb_UserGetAllData($userLogin);
  820. if (!empty($userData)) {
  821. $userAddress = $userData[$userLogin]['fulladress'];
  822. //login linking
  823. if ($linkType == 'login') {
  824. $result .= $this->createLink($boxId, $linkType, array($userLogin));
  825. }
  826. //address linking
  827. if ($linkType == 'address') {
  828. if (!empty($userAddress)) {
  829. $result .= $this->createLink($boxId, $linkType, array($userAddress));
  830. } else {
  831. $result .= __('Something went wrong') . ': ' . __('Address') . ' ' . __('Empty');
  832. }
  833. }
  834. //login and address linking
  835. if ($linkType == 'loginaddress') {
  836. if (empty($userAddress)) {
  837. $userAddress = __('User is a hobo');
  838. }
  839. $result .= $this->createLink($boxId, $linkType, array($userLogin, $userAddress));
  840. }
  841. } else {
  842. $result .= __('Something went wrong') . ': ' . __('User') . ' (' . $userLogin . ') ' . __('Not exists');
  843. }
  844. }
  845. }
  846. } else {
  847. $result .= __('Something went wrong') . ': ' . __('ONU') . ' [' . $onuId . '] ' . __('Not exists');
  848. }
  849. } else {
  850. $result .= __('Something went wrong') . ': ' . __('box') . ' [' . $boxId . '] ' . __('Not exists');
  851. }
  852. return ($result);
  853. }
  854. /**
  855. * Renders splitters adding controls
  856. *
  857. * @param $boxID
  858. *
  859. * @return string
  860. */
  861. public function renderSplittersControls($boxID) {
  862. $inputs = __('Place a splitter/coupler in this box') . ':' . wf_nbsp();
  863. $inputs .= wf_Selector(self::ROUTE_SPLITTERADD, $this->splittersTypesList, '');
  864. $inputs .= wf_HiddenInput(self::ROUTE_BOXEDIT, $boxID);
  865. $inputs .= wf_Submit(__('Append'));
  866. $result = wf_Form('', 'POST', $inputs, 'glamour') . wf_delimiter(0);
  867. return ($result);
  868. }
  869. /**
  870. * Renders splitters list
  871. *
  872. * @param $boxID
  873. *
  874. * @return string
  875. *
  876. * @throws Exception
  877. */
  878. public function renderSplittersList($boxID) {
  879. $result = '';
  880. $boxID = ubRouting::filters($boxID, 'int');
  881. if (isset($this->allBoxes[$boxID])) {
  882. if (!empty($this->allSplittersLinks)) {
  883. $curBoxSplitters = array();
  884. foreach ($this->allSplittersLinks as $io => $each) {
  885. if ($each['boxid'] == $boxID) {
  886. $curBoxSplitters[] = $each;
  887. }
  888. }
  889. if (!empty($curBoxSplitters)) {
  890. $cells = wf_TableCell(__('Splitter') . ' / ' . __('Coupler'));
  891. $cells .= wf_TableCell(__('Actions'));
  892. $rows = wf_TableRow($cells, 'row1');
  893. foreach ($curBoxSplitters as $io => $each) {
  894. $cells = wf_TableCell($this->splittersTypesList[$each['splitter']]);
  895. $delLinkUrl = self::URL_ME . '&' . self::ROUTE_SPLITTERDEL . '=' . $each['id'] . '&' . self::ROUTE_BOXNAV . '=' . $each['boxid'];
  896. $actLinks = wf_JSAlert($delLinkUrl, web_delete_icon(), $this->messages->getDeleteAlert());
  897. $cells .= wf_TableCell($actLinks);
  898. $rows .= wf_TableRow($cells, 'row5');
  899. }
  900. $result .= wf_TableBody($rows, '50%', 0, 'sortable');
  901. } else {
  902. $result .= $this->messages->getStyledMessage(__('Nothing to show'), 'info');
  903. }
  904. } else {
  905. $result .= $this->messages->getStyledMessage(__('Nothing to show'), 'warning');
  906. }
  907. } else {
  908. $result .= $this->messages->getStyledMessage(__('Something went wrong') . ': ' . __('box') . ' [' . $boxID . '] ' . __('Not exists'), 'error');
  909. }
  910. return ($result);
  911. }
  912. /**
  913. * Adds a splitter to PON box
  914. *
  915. * @return string
  916. *
  917. * @throws Exception
  918. */
  919. public function addSplitter() {
  920. $result = '';
  921. if (ubRouting::checkPost(array(self::ROUTE_BOXEDIT, self::ROUTE_SPLITTERADD))) {
  922. $boxID = ubRouting::post(self::ROUTE_BOXEDIT, 'int');
  923. $newSplitterName = ubRouting::post(self::ROUTE_SPLITTERADD);
  924. $newSplitterNameF = ubRouting::filters($newSplitterName, 'mres');
  925. if (isset($this->allBoxes[$boxID])) {
  926. $this->splittersLinks->data('splitter', $newSplitterNameF);
  927. $this->splittersLinks->data('boxid', $boxID);
  928. $this->splittersLinks->create();
  929. log_register('PONBOX ADD SPLITTER TO BOX [' . $boxID . '] TYPE `' . $newSplitterName . '`');
  930. } else {
  931. $result .= __('Something went wrong') . ': ' . __('box') . ' [' . $boxID . '] ' . __('Not exists');
  932. }
  933. }
  934. return ($result);
  935. }
  936. /**
  937. * Generates a crosslink warning when a certain ONU is linked to several PON boxes
  938. *
  939. * @param false $userProfile
  940. *
  941. * @return string
  942. */
  943. public function renderCrossLinkWarning($userProfile = false) {
  944. $result = '';
  945. $message = __('More then one ponbox link exists for current ONU - does it live in separate multiverses?');
  946. if ($userProfile) {
  947. $result = wf_tag('span', false, '', 'style="color: #796616; font-size: 14px;"') . $message . wf_tag('span', true);
  948. } else {
  949. $result = $this->messages->getStyledMessage($message, 'warning');
  950. }
  951. return ($result);
  952. }
  953. /**
  954. * Rendering images processing form and controls
  955. *
  956. * @param $boxID
  957. *
  958. * @return string
  959. */
  960. public function renderBoxImageControls($boxID) {
  961. $photoStorage = new PhotoStorage(self::PHOTOSTORAGE_SCOPE, $boxID);
  962. $inputs = $photoStorage->renderUploadForm(true, base64_encode(self::URL_ME . '&' . self::ROUTE_BOXEDIT . '=' . $boxID));
  963. $inputs .= $photoStorage->renderImagesList();
  964. return ($inputs);
  965. }
  966. }