1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15:
16: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
17:
18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61:
62:
63: 64: 65: 66: 67: 68:
69: class cApiPropertyCollection extends ItemCollection {
70:
71: 72: 73: 74: 75:
76: public $client;
77:
78: 79: 80: 81: 82:
83: protected static $_entries;
84:
85: 86: 87: 88: 89:
90: protected static $_enableCache;
91:
92: 93: 94: 95: 96:
97: protected static $_cacheItemtypes;
98:
99: 100: 101: 102:
103: public function __construct($idclient = 0) {
104: global $cfg, $client, $lang;
105:
106: if (0 === $idclient) {
107:
108:
109: $idclient = $client;
110: }
111:
112: $this->client = cSecurity::toInteger($idclient);
113: parent::__construct($cfg['tab']['properties'], 'idproperty');
114: $this->_setItemClass('cApiProperty');
115:
116:
117: $this->_setJoinPartner('cApiClientCollection');
118:
119: if (!isset(self::$_enableCache)) {
120: if (isset($cfg['properties']) && isset($cfg['properties']['properties']) && isset($cfg['properties']['properties']['enable_cache'])) {
121: self::$_enableCache = (bool) $cfg['properties']['properties']['enable_cache'];
122:
123: if (isset($cfg['properties']['properties']['itemtypes']) && is_array($cfg['properties']['properties']['itemtypes'])) {
124: self::$_cacheItemtypes = $cfg['properties']['properties']['itemtypes'];
125: foreach (self::$_cacheItemtypes as $name => $value) {
126: if ('%client%' == $value) {
127: self::$_cacheItemtypes[$name] = (int) $idclient;
128: } elseif ('%lang%' == $value) {
129: self::$_cacheItemtypes[$name] = (int) $lang;
130: } else {
131: unset(self::$_cacheItemtypes[$name]);
132: }
133: }
134: }
135: } else {
136: self::$_enableCache = false;
137: }
138: }
139:
140: if (self::$_enableCache && !isset(self::$_entries)) {
141: $this->_loadFromCache();
142: }
143: }
144:
145: 146: 147:
148: public static function reset() {
149: self::$_enableCache = false;
150: self::$_entries = array();
151: self::$_cacheItemtypes = array();
152: }
153:
154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171:
172: public function create($itemtype, $itemid, $type, $name, $value, $bDontEscape = false) {
173: global $auth;
174:
175: $item = parent::createNewItem();
176:
177: if (!$bDontEscape) {
178: $itemtype = $this->db->escape($itemtype);
179: $itemid = $this->db->escape($itemid);
180: $value = $this->db->escape($value);
181: $type = $this->db->escape($type);
182: $name = $this->db->escape($name);
183: }
184:
185: $item->set('idclient', $this->client);
186: $item->set('itemtype', $itemtype, false);
187: $item->set('itemid', $itemid, false);
188: $item->set('type', $type);
189: $item->set('name', $name);
190: $item->set('value', $value);
191:
192: $item->set('created', date('Y-m-d H:i:s'), false);
193: $item->set('author', $this->db->escape($auth->auth['uid']));
194: $item->store();
195:
196: if ($this->_useCache($itemtype, $itemid)) {
197: $this->_addToCache($item);
198: }
199:
200: return ($item);
201: }
202:
203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217:
218: public function getValue($itemtype, $itemid, $type, $name, $default = false) {
219: if ($this->_useCache($itemtype, $itemid)) {
220: return $this->_getValueFromCache($itemtype, $itemid, $type, $name, $default);
221: }
222:
223: $itemtype = $this->db->escape($itemtype);
224: $itemid = $this->db->escape($itemid);
225: $type = $this->db->escape($type);
226: $name = $this->db->escape($name);
227:
228: if (isset($this->client)) {
229: $this->select("idclient = " . (int) $this->client . " AND itemtype = '" . $itemtype . "' AND itemid = '" . $itemid . "' AND type = '" . $type . "' AND name = '" . $name . "'");
230: } else {
231:
232: $this->select("itemtype = '" . $itemtype . "' AND itemid = '" . $itemid . "' AND type = '" . $type . "' AND name = '" . $name . "'");
233: }
234:
235: if (($item = $this->next()) !== false) {
236: return (cSecurity::unescapeDB($item->get('value')));
237: }
238:
239: return $default;
240: }
241:
242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256:
257: public function getValuesByType($itemtype, $itemid, $type) {
258: if ($this->_useCache($itemtype, $itemid)) {
259: return $this->_getValuesByTypeFromCache($itemtype, $itemid, $type);
260: }
261:
262: $aResult = array();
263: $itemtype = $this->db->escape($itemtype);
264: $itemid = $this->db->escape($itemid);
265: $type = $this->db->escape($type);
266:
267: if (isset($this->client)) {
268: $this->select("idclient = " . (int) $this->client . " AND itemtype = '" . $itemtype . "' AND itemid = '" . $itemid . "' AND type = '" . $type . "'");
269: } else {
270:
271: $this->select("itemtype = '" . $itemtype . "' AND itemid = '" . $itemid . "' AND type = '" . $type . "'");
272: }
273:
274: while (($item = $this->next()) !== false) {
275: $aResult[$item->get('name')] = cSecurity::unescapeDB($item->get('value'));
276: }
277:
278: return $aResult;
279: }
280:
281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294:
295: public function getValuesOnlyByTypeName($type, $name) {
296: $aResult = array();
297: $type = $this->db->escape($type);
298: $name = $this->db->escape($name);
299:
300: $this->select("type = '" . $type . "' AND name = '" . $name . "");
301:
302: while (($item = $this->next()) !== false) {
303: $aResult[] = cSecurity::unescapeDB($item->get('value'));
304: }
305:
306: return $aResult;
307: }
308:
309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323: 324: 325: 326: 327:
328: public function setValue($itemtype, $itemid, $type, $name, $value, $idProp = 0) {
329: $itemtype = $this->db->escape($itemtype);
330: $itemid = $this->db->escape($itemid);
331: $type = $this->db->escape($type);
332: $name = $this->db->escape($name);
333: $value = $this->db->escape($value);
334: $idProp = (int) $idProp;
335:
336: if ($idProp == 0) {
337: $this->select("idclient = " . (int) $this->client . " AND itemtype = '" . $itemtype . "' AND itemid = '" . $itemid . "' AND type = '" . $type . "' AND name = '" . $name . "'");
338: } else {
339: $this->select("idclient = " . (int) $this->client . " AND itemtype = '" . $itemtype . "' AND itemid = '" . $itemid . "' AND idproperty = " . $idProp);
340: }
341:
342: if (($item = $this->next()) !== false) {
343: $item->set('value', $value);
344: $item->set('name', $name);
345: $item->set('type', $type);
346: $item->store();
347:
348: if ($this->_useCache($itemtype, $itemid)) {
349: $this->_addToCache($item);
350: }
351: } else {
352: $this->create($itemtype, $itemid, $type, $name, $value, true);
353: }
354: }
355:
356: 357: 358: 359: 360: 361: 362: 363: 364: 365: 366: 367: 368: 369:
370: public function deleteValue($itemtype, $itemid, $type, $name) {
371: $itemtype = $this->db->escape($itemtype);
372: $itemid = $this->db->escape($itemid);
373: $type = $this->db->escape($type);
374: $name = $this->db->escape($name);
375:
376: if (isset($this->client)) {
377: $where = "idclient = " . (int) $this->client . " AND itemtype = '" . $itemtype . "' AND itemid = '" . $itemid . "' AND type = '" . $type . "' AND name = '" . $name . "'";
378: } else {
379:
380: $where = "itemtype = '" . $itemtype . "' AND itemid = '" . $itemid . "' AND type = '" . $type . "' AND name = '" . $name . "'";
381: }
382:
383: $idproperties = $this->getIdsByWhereClause($where);
384:
385: $this->_deleteMultiple($idproperties);
386: if ($this->_useCache()) {
387: $this->_deleteFromCacheMultiple($idproperties);
388: }
389: }
390:
391: 392: 393: 394: 395: 396: 397:
398: public function getProperties($itemtype, $itemid) {
399: if ($this->_useCache($itemtype, $itemid)) {
400: return $this->_getPropertiesFromCache($itemtype, $itemid);
401: }
402:
403: $itemtype = $this->db->escape($itemtype);
404: $itemid = $this->db->escape($itemid);
405:
406: if (isset($this->client)) {
407: $this->select("idclient = " . (int) $this->client . " AND itemtype = '" . $itemtype . "' AND itemid = '" . $itemid . "'");
408: } else {
409:
410: $this->select("itemtype = '" . $itemtype . "' AND itemid = '" . $itemid . "'");
411: }
412:
413: $result[$itemid] = false;
414:
415: while (($item = $this->next()) !== false) {
416:
417: $result[$item->get('itemid')][$item->get('idproperty')] = array(
418: 0 => $item->get('type'),
419: 'type' => $item->get('type'),
420: 1 => $item->get('name'),
421: 'name' => $item->get('name'),
422: 2 => $item->get('value'),
423: 'value' => $item->get('value')
424: );
425: }
426: return $result;
427: }
428:
429: 430: 431: 432: 433: 434: 435: 436:
437: public function getAllValues($field, $fieldValue, $auth = NULL) {
438: $authString = '';
439: if (!is_null($auth) && sizeof($auth) > 0) {
440: $authString .= " AND author = '" . $auth->auth["uid"] . "'";
441: }
442:
443: if (isset($this->client)) {
444: $this->select("idclient = " . (int) $this->client . " AND " . $field . " = '" . $fieldValue . "'" . $authString, '', 'itemid');
445: } else {
446:
447: $this->select($field . " = '" . $fieldValue . "'" . $authString);
448: }
449:
450: $retValue = array();
451: while (($item = $this->next()) !== false) {
452: $dbLine = array(
453: 'idproperty' => $item->get('idproperty'),
454: 'idclient' => $item->get('idclient'),
455: 'itemtype' => $item->get('itemtype'),
456: 'itemid' => $item->get('itemid'),
457: 'type' => $item->get('type'),
458: 'name' => $item->get('name'),
459: 'value' => $item->get('value'),
460: 'author' => $item->get('author'),
461: 'created' => $item->get('created'),
462: 'modified' => $item->get('modified'),
463: 'modifiedby' => $item->get('modifiedby')
464: );
465: $retValue[] = $dbLine;
466: }
467: return $retValue;
468: }
469:
470: 471: 472: 473: 474: 475:
476: public function deleteProperties($itemtype, $itemid) {
477: $itemtype = $this->db->escape($itemtype);
478: $itemid = $this->db->escape($itemid);
479:
480: if (isset($this->client)) {
481: $where = "idclient = " . (int) $this->client . " AND itemtype = '" . $itemtype . "' AND itemid = '" . $itemid . "'";
482: } else {
483:
484: $where = "itemtype = '" . $itemtype . "' AND itemid = '" . $itemid . "'";
485: }
486:
487: $idproperties = $this->getIdsByWhereClause($where);
488:
489: $this->_deletePropertiesByIds($idproperties);
490: }
491:
492: 493: 494: 495: 496: 497:
498: public function deletePropertiesMultiple($itemtype, array $itemids) {
499: $itemtype = $this->db->escape($itemtype);
500: $itemids = array_map(array(
501: $this,
502: 'escape'
503: ), $itemids);
504:
505: $in = "'" . implode("', '", $itemids) . "'";
506:
507: if (isset($this->client)) {
508: $where = "idclient = " . (int) $this->client . " AND itemtype = '" . $itemtype . "' AND itemid IN (" . $in . ")";
509: } else {
510:
511: $where = "itemtype = '" . $itemtype . "' AND itemid IN (" . $in . ")";
512: }
513:
514: $idproperties = $this->getIdsByWhereClause($where);
515:
516: $this->_deletePropertiesByIds($idproperties);
517: }
518:
519: 520: 521: 522: 523:
524: public function changeClient($idclient) {
525: $this->client = (int) $idclient;
526: }
527:
528: 529: 530:
531: protected function _loadFromCache() {
532: global $client;
533: if (!isset(self::$_entries)) {
534: self::$_entries = array();
535: }
536:
537: $where = array();
538: foreach (self::$_cacheItemtypes as $itemtype => $itemid) {
539: if (is_numeric($itemid)) {
540: $where[] = "(itemtype = '" . $itemtype . "' AND itemid = " . $itemid . ")";
541: } else {
542: $where[] = "(itemtype = '" . $itemtype . "' AND itemid = '" . $itemid . "')";
543: }
544: }
545:
546: if (count($where) == 0) {
547: return;
548: }
549:
550: $where = "idclient = " . (int) $client . ' AND ' . implode(' OR ', $where);
551: $this->select($where);
552: while (($property = $this->next()) !== false) {
553: $this->_addToCache($property);
554: }
555: }
556:
557: protected function _useCache($itemtype = null, $itemid = null) {
558: global $client;
559: $ok = (self::$_enableCache && $this->client == $client);
560: if (!$ok) {
561: return $ok;
562: } elseif ($itemtype == null || $itemid == null) {
563: return $ok;
564: }
565:
566: foreach (self::$_cacheItemtypes as $name => $value) {
567: if ($itemtype == $value['itemtype'] || $itemid == $value['itemid']) {
568: return true;
569: }
570: }
571: }
572:
573: 574: 575: 576: 577: 578:
579: protected function _deletePropertiesByIds(array $ids) {
580: if (count($ids) > 0) {
581: $this->_deleteMultiple($ids);
582: if ($this->_useCache()) {
583: $this->_deleteFromCacheMultiple($ids);
584: }
585: }
586: }
587:
588: 589: 590: 591: 592:
593: protected function _addToCache($entry) {
594: global $client;
595: $data = $entry->toArray();
596: self::$_entries[$data['idproperty']] = $data;
597: }
598:
599: 600: 601: 602: 603:
604: protected function _deleteFromCache($id) {
605: if (isset(self::$_entries[$id])) {
606: unset(self::$_entries[$id]);
607: }
608: }
609:
610: 611: 612: 613: 614:
615: protected function _deleteFromCacheMultiple(array $ids) {
616: foreach ($ids as $id) {
617: if (isset(self::$_entries[$id])) {
618: unset(self::$_entries[$id]);
619: }
620: }
621: }
622:
623: 624: 625: 626: 627: 628: 629: 630: 631:
632: protected function _getValueFromCache($itemtype, $itemid, $type, $name, $default = false) {
633: foreach (self::$_entries as $id => $entry) {
634: if ($entry['itemtype'] == $itemtype && $entry['itemid'] == $itemid && $entry['type'] == $type && $entry['name'] == $name) {
635: return cSecurity::unescapeDB($entry['value']);
636: }
637: }
638:
639: return $default;
640: }
641:
642: 643: 644: 645: 646: 647: 648: 649: 650:
651: protected function _getValuesByTypeFromCache($itemtype, $itemid, $type) {
652: $result = array();
653:
654: foreach (self::$_entries as $id => $entry) {
655: if ($entry['itemtype'] == $itemtype && $entry['itemid'] == $itemid && $entry['type'] == $type) {
656: $result[$entry['name']] = cSecurity::unescapeDB($entry['value']);
657: }
658: }
659:
660: return $result;
661: }
662:
663: 664: 665: 666: 667: 668: 669:
670: public function _getPropertiesFromCache($itemtype, $itemid) {
671: $result = array();
672: $result[$itemid] = false;
673:
674: foreach (self::$_entries as $id => $entry) {
675: if ($entry['itemtype'] == $itemtype && $entry['itemid'] == $itemid) {
676:
677: $result[$entry['itemid']][$entry['idproperty']] = array(
678: 0 => $entry['type'],
679: 'type' => $entry['type'],
680: 1 => $entry['name'],
681: 'name' => $entry['name'],
682: 2 => $entry['value'],
683: 'value' => $entry['value']
684: );
685: }
686: }
687:
688: return $result;
689: }
690:
691: }
692:
693: 694: 695: 696: 697: 698:
699: class cApiProperty extends Item {
700:
701: 702: 703: 704: 705:
706: public $maximumLength;
707:
708: 709: 710: 711: 712:
713: public function __construct($mId = false) {
714: global $cfg;
715: parent::__construct($cfg['tab']['properties'], 'idproperty');
716:
717:
718: $this->maximumLength = array();
719: $this->maximumLength['itemtype'] = 64;
720: $this->maximumLength['itemid'] = 255;
721: $this->maximumLength['type'] = 96;
722: $this->maximumLength['name'] = 96;
723:
724: if ($mId !== false) {
725: $this->loadByPrimaryKey($mId);
726: }
727: }
728:
729: 730: 731: 732: 733:
734: public function store() {
735: global $auth;
736:
737: $this->set('modified', date('Y-m-d H:i:s'), false);
738: $this->set('modifiedby', $auth->auth['uid']);
739:
740: return parent::store();
741: }
742:
743: 744: 745: 746: 747: 748: 749: 750: 751:
752: public function setField($field, $value, $safe = true) {
753: if (array_key_exists($field, $this->maximumLength)) {
754: if (strlen($value) > $this->maximumLength[$field]) {
755: throw new cInvalidArgumentException("Tried to set field $field to value $value, but the field is too small. Truncated.");
756: }
757: }
758:
759: parent::setField($field, $value, $safe);
760: }
761:
762: }
763: