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