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: abstract class Mage_Core_Model_Resource_Db_Abstract extends Mage_Core_Model_Resource_Abstract
36: {
37: 38: 39:
40: const CHECKSUM_KEY_NAME= 'Checksum';
41:
42: 43: 44: 45: 46:
47: protected $_resources;
48:
49: 50: 51: 52: 53:
54: protected $_resourcePrefix;
55:
56: 57: 58: 59: 60:
61: protected $_connections = array();
62:
63: 64: 65: 66: 67:
68: protected $_resourceModel;
69:
70: 71: 72: 73: 74:
75: protected $_tables = array();
76:
77: 78: 79: 80: 81:
82: protected $_mainTable;
83:
84: 85: 86: 87: 88:
89: protected $_idFieldName;
90:
91: 92: 93: 94: 95:
96: protected $_isPkAutoIncrement = true;
97:
98: 99: 100: 101: 102:
103: protected $_useIsObjectNew = false;
104:
105: 106: 107: 108: 109:
110: protected $_fieldsForUpdate = array();
111:
112: 113: 114: 115: 116:
117: protected $_mainTableFields;
118:
119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133:
134: protected $_uniqueFields = null;
135:
136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147:
148: protected $_serializableFields = array();
149:
150: 151: 152: 153: 154: 155: 156:
157: protected function _init($mainTable, $idFieldName)
158: {
159: $this->_setMainTable($mainTable, $idFieldName);
160: }
161:
162: 163: 164: 165: 166: 167: 168: 169: 170:
171: protected function _setResource($connections, $tables = null)
172: {
173: $this->_resources = Mage::getSingleton('core/resource');
174:
175: if (is_array($connections)) {
176: foreach ($connections as $k=>$v) {
177: $this->_connections[$k] = $this->_resources->getConnection($v);
178: }
179: } else if (is_string($connections)) {
180: $this->_resourcePrefix = $connections;
181: }
182:
183: if (is_null($tables) && is_string($connections)) {
184: $this->_resourceModel = $this->_resourcePrefix;
185: } else if (is_array($tables)) {
186: foreach ($tables as $k => $v) {
187: $this->_tables[$k] = $this->_resources->getTableName($v);
188: }
189: } else if (is_string($tables)) {
190: $this->_resourceModel = $tables;
191: }
192: return $this;
193: }
194:
195: 196: 197: 198: 199: 200: 201: 202:
203: protected function _setMainTable($mainTable, $idFieldName = null)
204: {
205: $mainTableArr = explode('/', $mainTable);
206:
207: if (!empty($mainTableArr[1])) {
208: if (empty($this->_resourceModel)) {
209: $this->_setResource($mainTableArr[0]);
210: }
211: $this->_setMainTable($mainTableArr[1], $idFieldName);
212: } else {
213: $this->_mainTable = $mainTable;
214: if (is_null($idFieldName)) {
215: $idFieldName = $mainTable . '_id';
216: }
217: $this->_idFieldName = $idFieldName;
218: }
219:
220: return $this;
221: }
222:
223: 224: 225: 226: 227:
228: public function getIdFieldName()
229: {
230: if (empty($this->_idFieldName)) {
231: Mage::throwException(Mage::helper('core')->__('Empty identifier field name'));
232: }
233: return $this->_idFieldName;
234: }
235:
236: 237: 238: 239: 240: 241:
242: public function getMainTable()
243: {
244: if (empty($this->_mainTable)) {
245: Mage::throwException(Mage::helper('core')->__('Empty main table name'));
246: }
247: return $this->getTable($this->_mainTable);
248: }
249:
250: 251: 252: 253: 254: 255:
256: public function getTable($entityName)
257: {
258: if (is_array($entityName)) {
259: $cacheName = join('@', $entityName);
260: list($entityName, $entitySuffix) = $entityName;
261: } else {
262: $cacheName = $entityName;
263: $entitySuffix = null;
264: }
265:
266: if (isset($this->_tables[$cacheName])) {
267: return $this->_tables[$cacheName];
268: }
269:
270: if (strpos($entityName, '/')) {
271: if (!is_null($entitySuffix)) {
272: $modelEntity = array($entityName, $entitySuffix);
273: } else {
274: $modelEntity = $entityName;
275: }
276: $this->_tables[$cacheName] = $this->_resources->getTableName($modelEntity);
277: } else if (!empty($this->_resourceModel)) {
278: $entityName = sprintf('%s/%s', $this->_resourceModel, $entityName);
279: if (!is_null($entitySuffix)) {
280: $modelEntity = array($entityName, $entitySuffix);
281: } else {
282: $modelEntity = $entityName;
283: }
284: $this->_tables[$cacheName] = $this->_resources->getTableName($modelEntity);
285: } else {
286: if (!is_null($entitySuffix)) {
287: $entityName .= '_' . $entitySuffix;
288: }
289: $this->_tables[$cacheName] = $entityName;
290: }
291: return $this->_tables[$cacheName];
292: }
293:
294:
295: 296: 297: 298: 299: 300: 301:
302: public function getValueTable($entityName, $valueType)
303: {
304: return $this->getTable(array($entityName, $valueType));
305: }
306:
307: 308: 309: 310: 311: 312:
313: protected function _getConnection($connectionName)
314: {
315: if (isset($this->_connections[$connectionName])) {
316: return $this->_connections[$connectionName];
317: }
318: if (!empty($this->_resourcePrefix)) {
319: $this->_connections[$connectionName] = $this->_resources->getConnection(
320: $this->_resourcePrefix . '_' . $connectionName);
321: } else {
322: $this->_connections[$connectionName] = $this->_resources->getConnection($connectionName);
323: }
324:
325: return $this->_connections[$connectionName];
326: }
327:
328: 329: 330: 331: 332:
333: protected function _getReadAdapter()
334: {
335: $writeAdapter = $this->_getWriteAdapter();
336: if ($writeAdapter && $writeAdapter->getTransactionLevel() > 0) {
337:
338: return $writeAdapter;
339: }
340: return $this->_getConnection('read');
341: }
342:
343: 344: 345: 346: 347:
348: protected function _getWriteAdapter()
349: {
350: return $this->_getConnection('write');
351: }
352:
353: 354: 355: 356: 357:
358: public function getReadConnection()
359: {
360: return $this->_getReadAdapter();
361: }
362:
363: 364: 365: 366: 367: 368: 369: 370:
371: public function load(Mage_Core_Model_Abstract $object, $value, $field = null)
372: {
373: if (is_null($field)) {
374: $field = $this->getIdFieldName();
375: }
376:
377: $read = $this->_getReadAdapter();
378: if ($read && !is_null($value)) {
379: $select = $this->_getLoadSelect($field, $value, $object);
380: $data = $read->fetchRow($select);
381:
382: if ($data) {
383: $object->setData($data);
384: }
385: }
386:
387: $this->unserializeFields($object);
388: $this->_afterLoad($object);
389:
390: return $this;
391: }
392:
393: 394: 395: 396: 397: 398: 399: 400:
401: protected function _getLoadSelect($field, $value, $object)
402: {
403: $field = $this->_getReadAdapter()->quoteIdentifier(sprintf('%s.%s', $this->getMainTable(), $field));
404: $select = $this->_getReadAdapter()->select()
405: ->from($this->getMainTable())
406: ->where($field . '=?', $value);
407: return $select;
408: }
409:
410: 411: 412: 413: 414: 415:
416: public function save(Mage_Core_Model_Abstract $object)
417: {
418: if ($object->isDeleted()) {
419: return $this->delete($object);
420: }
421:
422: $this->_serializeFields($object);
423: $this->_beforeSave($object);
424: $this->_checkUnique($object);
425: if (!is_null($object->getId()) && (!$this->_useIsObjectNew || !$object->isObjectNew())) {
426: $condition = $this->_getWriteAdapter()->quoteInto($this->getIdFieldName().'=?', $object->getId());
427: 428: 429:
430: if ($this->_isPkAutoIncrement) {
431: $data = $this->_prepareDataForSave($object);
432: unset($data[$this->getIdFieldName()]);
433: $this->_getWriteAdapter()->update($this->getMainTable(), $data, $condition);
434: } else {
435: $select = $this->_getWriteAdapter()->select()
436: ->from($this->getMainTable(), array($this->getIdFieldName()))
437: ->where($condition);
438: if ($this->_getWriteAdapter()->fetchOne($select) !== false) {
439: $data = $this->_prepareDataForSave($object);
440: unset($data[$this->getIdFieldName()]);
441: if (!empty($data)) {
442: $this->_getWriteAdapter()->update($this->getMainTable(), $data, $condition);
443: }
444: } else {
445: $this->_getWriteAdapter()->insert($this->getMainTable(), $this->_prepareDataForSave($object));
446: }
447: }
448: } else {
449: $bind = $this->_prepareDataForSave($object);
450: if ($this->_isPkAutoIncrement) {
451: unset($bind[$this->getIdFieldName()]);
452: }
453: $this->_getWriteAdapter()->insert($this->getMainTable(), $bind);
454:
455: $object->setId($this->_getWriteAdapter()->lastInsertId($this->getMainTable()));
456:
457: if ($this->_useIsObjectNew) {
458: $object->isObjectNew(false);
459: }
460: }
461:
462: $this->unserializeFields($object);
463: $this->_afterSave($object);
464:
465: return $this;
466: }
467:
468: 469: 470: 471: 472: 473: 474: 475:
476: public function forsedSave(Mage_Core_Model_Abstract $object)
477: {
478: $this->_beforeSave($object);
479: $bind = $this->_prepareDataForSave($object);
480: $adapter = $this->_getWriteAdapter();
481:
482: if (!is_null($object->getId()) && $this->_isPkAutoIncrement) {
483: unset($bind[$this->getIdFieldName()]);
484: $condition = $adapter->quoteInto($this->getIdFieldName().'=?', $object->getId());
485: $adapter->update($this->getMainTable(), $bind, $condition);
486: } else {
487: $adapter->insertOnDuplicate($this->getMainTable(), $bind, $this->_fieldsForUpdate);
488: $object->setId($adapter->lastInsertId($this->getMainTable()));
489: }
490:
491: $this->_afterSave($object);
492:
493: return $this;
494: }
495:
496: 497: 498: 499: 500: 501:
502: public function delete(Mage_Core_Model_Abstract $object)
503: {
504: $this->_beforeDelete($object);
505: $this->_getWriteAdapter()->delete(
506: $this->getMainTable(),
507: $this->_getWriteAdapter()->quoteInto($this->getIdFieldName() . '=?', $object->getId())
508: );
509: $this->_afterDelete($object);
510: return $this;
511: }
512:
513: 514: 515: 516: 517: 518:
519: public function addUniqueField($field)
520: {
521: if (is_null($this->_uniqueFields)) {
522: $this->_initUniqueFields();
523: }
524: if (is_array($this->_uniqueFields) ) {
525: $this->_uniqueFields[] = $field;
526: }
527: return $this;
528: }
529:
530: 531: 532: 533: 534:
535: public function resetUniqueField()
536: {
537: $this->_uniqueFields = array();
538: return $this;
539: }
540:
541: 542: 543: 544: 545:
546: public function unserializeFields(Mage_Core_Model_Abstract $object)
547: {
548: foreach ($this->_serializableFields as $field => $parameters) {
549: list($serializeDefault, $unserializeDefault) = $parameters;
550: $this->_unserializeField($object, $field, $unserializeDefault);
551: }
552: }
553:
554: 555: 556: 557: 558:
559: protected function _initUniqueFields()
560: {
561: $this->_uniqueFields = array();
562: return $this;
563: }
564:
565: 566: 567: 568: 569:
570: public function getUniqueFields()
571: {
572: if (is_null($this->_uniqueFields)) {
573: $this->_initUniqueFields();
574: }
575: return $this->_uniqueFields;
576: }
577:
578: 579: 580: 581: 582: 583:
584: protected function _prepareDataForSave(Mage_Core_Model_Abstract $object)
585: {
586: return $this->_prepareDataForTable($object, $this->getMainTable());
587: }
588:
589: 590: 591: 592: 593: 594: 595:
596: public function hasDataChanged($object)
597: {
598: if (!$object->getOrigData()) {
599: return true;
600: }
601:
602: $fields = $this->_getWriteAdapter()->describeTable($this->getMainTable());
603: foreach (array_keys($fields) as $field) {
604: if ($object->getOrigData($field) != $object->getData($field)) {
605: return true;
606: }
607: }
608:
609: return false;
610: }
611:
612: 613: 614: 615: 616: 617: 618:
619: protected function _prepareValueForSave($value, $type)
620: {
621: return $this->_prepareTableValueForSave($value, $type);
622: }
623:
624: 625: 626: 627: 628: 629: 630:
631: protected function _checkUnique(Mage_Core_Model_Abstract $object)
632: {
633: $existent = array();
634: $fields = $this->getUniqueFields();
635: if (!empty($fields)) {
636: if (!is_array($fields)) {
637: $this->_uniqueFields = array(
638: array(
639: 'field' => $fields,
640: 'title' => $fields
641: ));
642: }
643:
644: $data = new Varien_Object($this->_prepareDataForSave($object));
645: $select = $this->_getWriteAdapter()->select()
646: ->from($this->getMainTable());
647:
648: foreach ($fields as $unique) {
649: $select->reset(Zend_Db_Select::WHERE);
650:
651: if (is_array($unique['field'])) {
652: foreach ($unique['field'] as $field) {
653: $select->where($field . '=?', trim($data->getData($field)));
654: }
655: } else {
656: $select->where($unique['field'] . '=?', trim($data->getData($unique['field'])));
657: }
658:
659: if ($object->getId() || $object->getId() === '0') {
660: $select->where($this->getIdFieldName() . '!=?', $object->getId());
661: }
662:
663: $test = $this->_getWriteAdapter()->fetchRow($select);
664: if ($test) {
665: $existent[] = $unique['title'];
666: }
667: }
668: }
669:
670: if (!empty($existent)) {
671: if (count($existent) == 1 ) {
672: $error = Mage::helper('core')->__('%s already exists.', $existent[0]);
673: } else {
674: $error = Mage::helper('core')->__('%s already exist.', implode(', ', $existent));
675: }
676: Mage::throwException($error);
677: }
678: return $this;
679: }
680:
681: 682: 683: 684: 685:
686: public function afterLoad(Mage_Core_Model_Abstract $object)
687: {
688: $this->_afterLoad($object);
689: }
690:
691: 692: 693: 694: 695: 696:
697: protected function _afterLoad(Mage_Core_Model_Abstract $object)
698: {
699: return $this;
700: }
701:
702: 703: 704: 705: 706: 707:
708: protected function _beforeSave(Mage_Core_Model_Abstract $object)
709: {
710: return $this;
711: }
712:
713: 714: 715: 716: 717: 718:
719: protected function _afterSave(Mage_Core_Model_Abstract $object)
720: {
721: return $this;
722: }
723:
724: 725: 726: 727: 728: 729:
730: protected function _beforeDelete(Mage_Core_Model_Abstract $object)
731: {
732: return $this;
733: }
734:
735: 736: 737: 738: 739: 740:
741: protected function _afterDelete(Mage_Core_Model_Abstract $object)
742: {
743: return $this;
744: }
745:
746: 747: 748: 749: 750:
751: protected function _serializeFields(Mage_Core_Model_Abstract $object)
752: {
753: foreach ($this->_serializableFields as $field => $parameters) {
754: list($serializeDefault, $unserializeDefault) = $parameters;
755: $this->_serializeField($object, $field, $serializeDefault, isset($parameters[2]));
756: }
757: }
758:
759: 760: 761: 762: 763: 764:
765: public function getChecksum($table)
766: {
767: if (!$this->_getReadAdapter()) {
768: return false;
769: }
770: $checksum = $this->_getReadAdapter()->getTablesChecksum($table);
771: if (count($checksum) == 1) {
772: return $checksum[$table];
773: }
774: return $checksum;
775: }
776: }
777: