1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
14:
15: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
16:
17: plugin_include('repository', 'custom/FrontendNavigation.php');
18:
19: 20: 21: 22: 23: 24:
25: class pApiTree {
26:
27: 28: 29: 30: 31:
32: protected $_db = null;
33:
34: 35: 36: 37:
38: protected $_debug = false;
39:
40: 41: 42: 43:
44: protected $_table = array();
45:
46: 47: 48: 49:
50: protected $_lang = 1;
51:
52: 53: 54: 55:
56: protected $_client = 1;
57:
58: 59: 60: 61:
62: protected $_defaultLang = 1;
63:
64: 65: 66: 67:
68: protected $_logger = null;
69:
70: 71: 72: 73:
74: protected $_user = '';
75:
76: 77: 78: 79:
80: protected $_treeStatus = array();
81:
82: 83: 84: 85:
86: protected $_uuid = '';
87:
88: 89: 90: 91:
92: protected $_arrInFilters = array('htmlspecialchars', 'addslashes');
93:
94: 95: 96: 97:
98: protected $_arrOutFilters = array('stripslashes', 'htmldecode');
99:
100: 101: 102: 103: 104: 105: 106: 107:
108: public function __construct($uuid) {
109: $cfg = cRegistry::getConfig();
110: $auth = cRegistry::getAuth();
111:
112: $this->_db = cRegistry::getDb();
113: $this->_table = $cfg['tab'];
114: $this->_lang = cRegistry::getLanguageId();
115: $this->_client = cRegistry::getClientId();
116:
117: $this->_uuid = $uuid;
118:
119: $this->_user = new cApiUser($auth->auth['uid']);
120: $this->loadTreeStatus();
121: }
122:
123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134:
135: public function pApiTree($uuid) {
136: cDeprecated('This method is deprecated and is not needed any longer. Please use __construct() as constructor function.');
137: return $this->__construct($uuid);
138: }
139:
140: 141: 142: 143: 144: 145: 146: 147: 148: 149:
150: public function fetchTree($parentId = false, $level = 0, $useTreeStatus = true) {
151:
152:
153: $sql = "SELECT
154: tree.idpica_alloc, tree.parentid, tree.sortorder
155: FROM
156: " . $this->_table['pica_alloc'] . " as tree";
157:
158: if ($parentId === false) {
159: $sql .= " WHERE tree.parentid = '0'";
160: } else {
161: $sql .= " WHERE tree.parentid = " . cSecurity::toInteger($parentId);
162: }
163:
164: $sql .= " ORDER BY sortorder ASC";
165:
166: $this->_db->query($sql);
167:
168: $result_tmp = array();
169: while ($this->_db->nextRecord()) {
170:
171: $item = $this->fetchItemNameLang($this->_db->f('idpica_alloc'));
172:
173:
174: if ($item === false) {
175: continue;
176: }
177:
178: $itemStatus = 'expanded';
179:
180: if ($useTreeStatus) {
181: if (is_array($this->_treeStatus) && array_key_exists($this->_db->f('idpica_alloc'), $this->_treeStatus)) {
182: $itemStatus = 'collapsed';
183: }
184: }
185:
186: $rs = array(
187: 'idpica_alloc' => $this->_db->f('idpica_alloc'),
188: 'parentid' => ($this->_db->f('parentid') == NULL) ? false : $this->_db->f('parentid'),
189: 'sortorder' => $this->_db->f('sortorder'),
190: 'name' => $this->_outFilter($item['name']),
191: 'idlang' => $item['idlang'],
192: 'level' => $level,
193: 'status' => $itemStatus,
194: 'online' => $item['online']
195: );
196:
197: array_push($result_tmp, $rs);
198: }
199:
200: if (count($result_tmp) > 0) {
201: $result = array();
202:
203: foreach ($result_tmp as $rs) {
204: $children = $this->fetchTree($rs['idpica_alloc'], ($level + 1), $useTreeStatus);
205: if ($children !== false && $rs['status'] == 'expanded') {
206: $rs['children'] = $children;
207: }
208: array_push($result, $rs);
209: }
210: return $result;
211: } else {
212: return false;
213: }
214: }
215:
216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228:
229: public function fetchTreeIds($parentId = false, $level = 0, $showOffline = false) {
230:
231:
232: $sql = "SELECT
233: tree.idpica_alloc, tree.parentid, tree.sortorder
234: FROM
235: " . $this->_table['pica_alloc'] . " as tree";
236:
237: if ($parentId === false) {
238: $sql .= " WHERE tree.parentid IS NULL";
239: } else {
240: $sql .= " WHERE tree.parentid = " . cSecurity::toInteger($parentId);
241: }
242:
243: $sql .= " ORDER BY sortorder ASC";
244:
245: if ($this->_debug) {
246: print "<!-- "; print $sql; print " -->";
247: }
248:
249: $this->_db->query($sql);
250:
251: $result_tmp = array();
252: while ($this->_db->nextRecord()) {
253:
254: $item = $this->fetchItemNameLang($this->_db->f('idpica_alloc'));
255:
256: if ($showOffline || $item['online'] == 1) {
257: $rs = array(
258: 'idpica_alloc' => $this->_db->f('idpica_alloc')
259: );
260:
261: array_push($result_tmp, $rs);
262: }
263: }
264:
265: if (count($result_tmp) > 0) {
266: $result = array();
267: foreach ($result_tmp as $rs) {
268: $children = $this->fetchTreeIds($rs['idpica_alloc'], $level + 1, $showOffline);
269: if ($children !== false) {
270: $rs['children'] = $children;
271: }
272: array_push($result, $rs);
273: }
274: return $result;
275: } else {
276: return false;
277: }
278: }
279:
280: 281: 282: 283: 284: 285: 286: 287: 288:
289: public function setTreeStatus($idpica_alloc) {
290: $idpica_alloc = cSecurity::toInteger($idpica_alloc);
291: if (is_array($this->_treeStatus) && array_key_exists($idpica_alloc, $this->_treeStatus)) {
292: unset($this->_treeStatus[$idpica_alloc]);
293: } else {
294: $this->_treeStatus[$idpica_alloc] = true;
295: }
296: $this->_user->setProperty("expandstate", $this->_uuid, serialize($this->_treeStatus));
297: }
298:
299: 300: 301: 302: 303: 304:
305: public function loadTreeStatus() {
306: $status = $this->_user->getProperty("expandstate", $this->_uuid);
307: if ($status !== false) {
308: $this->_treeStatus = unserialize($status);
309: }
310: }
311:
312: 313: 314: 315: 316: 317: 318: 319:
320: public function fetchParent($idpica_alloc) {
321: $sql = "SELECT idpica_alloc FROM ".$this->_table['pica_alloc']." WHERE parentId = " . cSecurity::toInteger($idpica_alloc);
322: $this->_db->query($sql);
323:
324: if ($this->_db->nextRecord()) {
325: return $this->fetchItem($this->_db->f('idpica_alloc'));
326: } else {
327: return false;
328: }
329: }
330:
331: 332: 333:
334: public function fetchParents () {}
335:
336: 337: 338: 339: 340: 341: 342: 343: 344:
345: protected function fetchLevel($parentId = false, $showOffline = false) {
346:
347: $sql = "SELECT
348: tree.idpica_alloc, tree.parentid, tree.sortorder
349: FROM
350: " . $this->_table['pica_alloc'] . " as tree
351: LEFT JOIN ".$this->_table['pica_lang']." as treelang USING (idpica_alloc)";
352:
353: if ($parentId === false) {
354: $sql .= " WHERE tree.parentid IS NULL";
355: } else {
356: $sql .= " WHERE tree.parentid = " . cSecurity::toInteger($parentId);
357: }
358:
359: if ($showOffline === false) {
360: $sql .= " AND treelang.online = 1";
361: }
362:
363: $sql .= " ORDER BY sortorder ASC";
364:
365: $this->_db->query($sql);
366:
367: $result_tmp = array();
368: while ($this->_db->nextRecord()) {
369: $item = $this->
370: fetchItemNameLang($this->_db->f('idpica_alloc'));
371:
372: $itemStatus = 'expanded';
373: if (is_array($this->_treeStatus) && array_key_exists($this->_db->f('idpica_alloc'), $this->_treeStatus)) {
374: $itemStatus = 'collapsed';
375: }
376:
377: $rs = array(
378: 'idpica_alloc' => $this->_db->f('idpica_alloc'),
379: 'parentid' => ($this->_db->f('parentid') == NULL) ? false : $this->_db->f('parentid'),
380: 'sortorder' => $this->_db->f('sortorder'),
381: 'name' => $this->_outFilter($item['name']),
382: 'idlang' => $item['idlang'],
383: 'level' => 0,
384: 'status' => $itemStatus,
385: 'online' => $item['online']
386: );
387:
388: array_push($result_tmp, $rs);
389: }
390:
391: return $result_tmp;
392: }
393:
394: 395: 396: 397: 398: 399: 400: 401:
402: public function storeItem($treeItem) {
403:
404: if (!$treeItem['idpica_alloc']) {
405:
406: $treeItem['sortorder'] = $this->_fetchMaxOrder($treeItem['parentid']) + 1;
407:
408: if ($treeItem['parentid'] == 'root') {
409: $treeItem['parentid'] = 'NULL';
410: }
411:
412: $treeItem['name'] = $this->_inFilter($treeItem['name']);
413:
414: $sql = "INSERT INTO " . $this->_table['pica_alloc'] . "
415: (parentid, sortorder)
416: VALUES
417: (" . cSecurity::toInteger($treeItem['parentid']) . ", " . cSecurity::toInteger($treeItem['sortorder']) . ")";
418: $this->_db->query($sql);
419: $treeItem['idpica_alloc'] = $this->_db->getLastInsertedId();
420: $sql = "INSERT INTO " . $this->_table['pica_lang'] . "
421: (idpica_alloc, idlang, name)
422: VALUES
423: (" . cSecurity::toInteger($treeItem['idpica_alloc']) . ", " . cSecurity::toInteger($this->_lang) . ", '" . $this->_db->escape($treeItem['name']) . "')";
424: $this->_db->query($sql);
425:
426: } else {
427: $treeItem['name'] = $this->_inFilter($treeItem['name']);
428:
429: $sql = "SELECT * FROM " . $this->_table['pica_lang'] . " WHERE idpica_alloc = " . cSecurity::toInteger($treeItem['idpica_alloc']) . " AND idlang = " . cSecurity::toInteger($this->_lang);
430: $this->_db->query($sql);
431:
432: if ($this->_db->numRows() > 0) {
433:
434: $sql = "UPDATE " . $this->_table['pica_lang'] . " SET name = '" . $this->_db->escape($treeItem['name']) . "' WHERE idpica_alloc = " . cSecurity::toInteger($treeItem['idpica_alloc']) . "
435: AND idlang = " . cSecurity::toInteger($this->_lang);
436: } else {
437:
438: $sql = "SELECT * FROM " . $this->_table['pica_lang'] . " WHERE idpica_alloc = " . $treeItem['idpica_alloc'] . " ORDER BY idlang";
439: $this->_db->query($sql);
440:
441: if ($this->_db->nextRecord()) {
442: $online_status = $this->_db->f('online');
443: } else {
444: $online_status = 0;
445: }
446:
447:
448: $sql = "INSERT INTO " . $this->_table['pica_lang'] . "(idpica_alloc, idlang, name, online) VALUES (".cSecurity::toInteger($treeItem['idpica_alloc']).", ".cSecurity::toInteger($this->_lang).",
449: '".$this->_db->escape($treeItem['name'])."', ".cSecurity::toInteger($online_status).")";
450: }
451:
452: $this->_db->query($sql);
453: }
454:
455: return $treeItem;
456: }
457:
458: 459: 460: 461: 462: 463: 464:
465: public function setOnline($idpica_alloc) {
466: $this->_switchOnOffline($idpica_alloc, 1);
467: }
468:
469: 470: 471: 472: 473: 474: 475:
476: public function setOffline($idpica_alloc) {
477: $this->_switchOnOffline($idpica_alloc, 0);
478: }
479:
480: 481: 482: 483: 484: 485: 486: 487:
488: protected function _switchOnOffline($idpica_alloc, $status) {
489: $sql = "UPDATE " . $this->_table['pica_lang'] . " SET online = " . cSecurity::toInteger($status) . " WHERE idpica_alloc = " . cSecurity::toInteger($idpica_alloc) . "
490: AND idlang = " . cSecurity::toInteger($this->_lang);
491: $this->_db->query($sql);
492: }
493:
494: 495: 496: 497: 498: 499: 500:
501: public function itemMoveUp($idpica_alloc) {
502: $treeItem = $this->fetchItem($idpica_alloc);
503: $treeItem_old = $treeItem;
504: $treeItem['sortorder']--;
505:
506: if ($treeItem['sortorder'] < $treeItem_old['sortorder']) {
507: if ($treeItem['sortorder'] >= 1) {
508: $this->_decreaseOrder($treeItem['parentid'], $treeItem_old['sortorder']);
509: $this->_increaseOrder($treeItem['parentid'], $treeItem['sortorder']);
510: } else {
511: $treeItem['sortorder'] = $treeItem_old['sortorder'];
512: }
513: }
514:
515: $sql = "UPDATE " . $this->_table['pica_alloc'] . " SET sortorder = " . $treeItem['sortorder'] . " WHERE idpica_alloc = " . cSecurity::toInteger($idpica_alloc);
516: $this->_db->query($sql);
517: }
518:
519: 520: 521:
522: public function itemMoveDown() {}
523:
524: 525: 526: 527: 528: 529: 530: 531:
532: public function deleteItem($idpica_alloc) {
533: $sql = "DELETE FROM " . $this->_table['pica_alloc'] . " WHERE idpica_alloc = " . cSecurity::toInteger($idpica_alloc);
534: $this->_db->query($sql);
535:
536: $sql = "DELETE FROM " . $this->_table['pica_lang'] . " WHERE idpica_alloc = " . cSecurity::toInteger($idpica_alloc);
537: $this->_db->query($sql);
538:
539: $sql = "DELETE FROM " . $this->_table['pica_alloc_con'] . " WHERE idpica_alloc = " . cSecurity::toInteger($idpica_alloc);
540: $this->_db->query($sql);
541:
542: return true;
543: }
544:
545: 546: 547: 548: 549: 550: 551: 552:
553: function fetchItem($idpica_alloc) {
554: $sql = "SELECT parentid, sortorder FROM " . $this->_table['pica_alloc'] . " WHERE idpica_alloc = " . cSecurity::toInteger($idpica_alloc);
555: $this->_db->query($sql);
556:
557: $item = $this->fetchItemNameLang($idpica_alloc);
558:
559: if ($this->_db->nextRecord()) {
560: $row = array(
561: 'idpica_alloc' => $idpica_alloc,
562: 'parentid' => ($this->_db->f('parentid') == NULL) ? false : $this->_db->f('parentid'),
563: 'sortorder' => $this->_db->f('sortorder'),
564: 'name' => $item['name'],
565: 'idlang' => $item['idlang'],
566: 'online' => $item['online']
567: );
568: return $row;
569: } else {
570: return false;
571: }
572: }
573:
574: 575: 576: 577: 578: 579: 580: 581:
582: public function fetchItemNameLang($idpica_alloc) {
583:
584:
585: $db = cRegistry::getDb();
586:
587: $sql = "SELECT name, idlang, online FROM " . $this->_table['pica_lang'] . " WHERE idpica_alloc = " . cSecurity::toInteger($idpica_alloc) . " AND idlang = " . cSecurity::toInteger($this->_lang);
588: $db->query($sql);
589:
590: $result = array();
591: if ($db->nextRecord()) {
592:
593: $result['name'] = $this->_outFilter($db->f('name'));
594: $result['idlang'] = $db->f('idlang');
595: $result['online'] = $db->f('online');
596:
597: } else {
598: return false;
599: }
600:
601: return $result;
602: }
603:
604: 605: 606: 607: 608: 609: 610: 611:
612: protected function _fetchMaxOrder($parentId = false) {
613:
614: if ($parentId == 'root') {
615: $parentId = false;
616: }
617:
618: $sql = "SELECT MAX(sortorder) as max FROM " . $this->_table['pica_alloc'];
619: if ($parentId === false) {
620: $sql .= " WHERE parentid = 0";
621: } else {
622: $sql .= " WHERE parentid = " . cSecurity::toInteger($parentId);
623: }
624: $this->_db->query($sql);
625: if ($this->_db->nextRecord()) {
626: return $this->_db->f('max');
627: } else {
628: return 0;
629: }
630: }
631:
632: 633: 634: 635: 636: 637: 638: 639:
640: protected function _decreaseOrder($parentId = false, $fromOrder) {
641: $sql = "UPDATE " . $this->_table['pica_alloc'] . " SET sortorder = sortorder - 1 WHERE sortorder >= " . cSecurity::toInteger($fromOrder);
642: if ($parentId === false) {
643: $sql .= " AND parentid IS NULL";
644: } else {
645: $sql .= " AND parentid = " . cSecurity::toInteger($parentId);
646: }
647: $this->_db->query($sql);
648: }
649:
650: 651: 652: 653: 654: 655: 656: 657:
658: protected function _increaseOrder($parentId = false, $fromOrder) {
659: $sql = "UPDATE " . $this->_table['pica_alloc'] . " SET sortorder = sortorder + 1 WHERE sortorder >= " . cSecurity::toInteger($fromOrder);
660: if ($parentId === false) {
661: $sql .= " AND parentid IS NULL";
662: } else {
663: $sql .= " AND parentid = " . cSecurity::toInteger($parentId);
664: }
665: $this->_db->query($sql);
666: }
667:
668: 669: 670: 671: 672: 673:
674: public function setFilters($arrInFilters = array(), $arrOutFilters = array()) {
675: $this->_arrInFilters = $arrInFilters;
676: $this->_arrOutFilters = $arrOutFilters;
677: }
678:
679: 680: 681: 682: 683: 684:
685: protected function _inFilter($data) {
686:
687: foreach ($this->_arrInFilters as $_function) {
688: if (function_exists($_function)) {
689: $data = $_function($data);
690: }
691: }
692:
693: return $data;
694: }
695:
696: 697: 698: 699: 700: 701:
702: protected function _outFilter($data) {
703:
704: foreach ($this->_arrOutFilters as $_function) {
705: if (function_exists($_function)) {
706: $data = $_function($data);
707: }
708: }
709:
710: return $data;
711: }
712: }
713: