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