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_Eav_Model_Entity_Attribute_Abstract extends Mage_Core_Model_Abstract
36: implements Mage_Eav_Model_Entity_Attribute_Interface
37: {
38: const TYPE_STATIC = 'static';
39:
40: 41: 42: 43: 44:
45: protected $_name;
46:
47: 48: 49: 50: 51:
52: protected $_entity;
53:
54: 55: 56: 57: 58:
59: protected $_backend;
60:
61: 62: 63: 64: 65:
66: protected $_frontend;
67:
68: 69: 70: 71: 72:
73: protected $_source;
74:
75: 76: 77: 78: 79:
80: protected $_attributeIdCache = array();
81:
82: 83: 84: 85: 86:
87: protected $_dataTable = null;
88:
89: 90: 91:
92: protected function _construct()
93: {
94: $this->_init('eav/entity_attribute');
95: }
96:
97: 98: 99: 100: 101: 102: 103:
104: public function loadByCode($entityType, $code)
105: {
106: Varien_Profiler::start('_LOAD_ATTRIBUTE_BY_CODE__');
107: if (is_numeric($entityType)) {
108: $entityTypeId = $entityType;
109: } elseif (is_string($entityType)) {
110: $entityType = Mage::getModel('eav/entity_type')->loadByCode($entityType);
111: }
112: if ($entityType instanceof Mage_Eav_Model_Entity_Type) {
113: $entityTypeId = $entityType->getId();
114: }
115: if (empty($entityTypeId)) {
116: throw Mage::exception('Mage_Eav', Mage::helper('eav')->__('Invalid entity supplied.'));
117: }
118: $this->_getResource()->loadByCode($this, $entityTypeId, $code);
119: $this->_afterLoad();
120: Varien_Profiler::stop('_LOAD_ATTRIBUTE_BY_CODE__');
121: return $this;
122: }
123:
124: 125: 126: 127: 128:
129: public function getConfig()
130: {
131: return $this;
132: }
133:
134: 135: 136: 137: 138:
139: public function getName()
140: {
141: return $this->_getData('attribute_code');
142: }
143:
144: 145: 146: 147: 148: 149:
150: public function setAttributeId($data)
151: {
152: $this->_data['attribute_id'] = $data;
153: return $this;
154: }
155:
156: 157: 158: 159: 160:
161: public function getAttributeId()
162: {
163: return $this->_getData('attribute_id');
164: }
165:
166: public function setAttributeCode($data)
167: {
168: return $this->setData('attribute_code', $data);
169: }
170:
171: public function getAttributeCode()
172: {
173: return $this->_getData('attribute_code');
174: }
175:
176: public function setAttributeModel($data)
177: {
178: return $this->setData('attribute_model', $data);
179: }
180:
181: public function getAttributeModel()
182: {
183: return $this->_getData('attribute_model');
184: }
185:
186: public function setBackendType($data)
187: {
188: return $this->setData('backend_type', $data);
189: }
190:
191: public function getBackendType()
192: {
193: return $this->_getData('backend_type');
194: }
195:
196: public function setBackendModel($data)
197: {
198: return $this->setData('backend_model', $data);
199: }
200:
201: public function getBackendModel()
202: {
203: return $this->_getData('backend_model');
204: }
205:
206: public function setBackendTable($data)
207: {
208: return $this->setData('backend_table', $data);
209: }
210:
211: public function getIsVisibleOnFront()
212: {
213: return $this->_getData('is_visible_on_front');
214: }
215:
216: public function getDefaultValue()
217: {
218: return $this->_getData('default_value');
219: }
220:
221: public function getAttributeSetId()
222: {
223: return $this->_getData('attribute_set_id');
224: }
225:
226: public function setAttributeSetId($id)
227: {
228: $this->_data['attribute_set_id'] = $id;
229: return $this;
230: }
231:
232: public function getEntityTypeId()
233: {
234: return $this->_getData('entity_type_id');
235: }
236:
237: public function setEntityTypeId($id)
238: {
239: $this->_data['entity_type_id'] = $id;
240: return $this;
241: }
242:
243: public function setEntityType($type)
244: {
245: $this->setData('entity_type', $type);
246: return $this;
247: }
248:
249: 250: 251: 252: 253: 254:
255: public function getIsGlobal()
256: {
257: return $this->_getData('is_global');
258: }
259:
260: 261: 262: 263: 264: 265:
266: public function getAlias($entity = null)
267: {
268: $alias = '';
269: if (($entity === null) || ($entity->getType() !== $this->getEntity()->getType())) {
270: $alias .= $this->getEntity()->getType() . '/';
271: }
272: $alias .= $this->getAttributeCode();
273:
274: return $alias;
275: }
276:
277: 278: 279: 280: 281: 282:
283: public function setName($name)
284: {
285: return $this->setData('attribute_code', $name);
286: }
287:
288: 289: 290: 291: 292:
293: public function getEntityType()
294: {
295: return Mage::getSingleton('eav/config')->getEntityType($this->getEntityTypeId());
296: }
297:
298: 299: 300: 301: 302: 303:
304: public function setEntity($entity)
305: {
306: $this->_entity = $entity;
307: return $this;
308: }
309:
310: 311: 312: 313: 314:
315: public function getEntity()
316: {
317: if (!$this->_entity) {
318: $this->_entity = $this->getEntityType();
319: }
320: return $this->_entity;
321: }
322:
323: 324: 325: 326: 327:
328: public function getEntityIdField()
329: {
330: return $this->getEntity()->getValueEntityIdField();
331: }
332:
333: 334: 335: 336: 337:
338: public function getBackend()
339: {
340: if (empty($this->_backend)) {
341: if (!$this->getBackendModel()) {
342: $this->setBackendModel($this->_getDefaultBackendModel());
343: }
344: $backend = Mage::getModel($this->getBackendModel());
345: if (!$backend) {
346: throw Mage::exception('Mage_Eav', 'Invalid backend model specified: ' . $this->getBackendModel());
347: }
348: $this->_backend = $backend->setAttribute($this);
349: }
350:
351: return $this->_backend;
352: }
353:
354: 355: 356: 357: 358:
359: public function getFrontend()
360: {
361: if (empty($this->_frontend)) {
362: if (!$this->getFrontendModel()) {
363: $this->setFrontendModel($this->_getDefaultFrontendModel());
364: }
365: $this->_frontend = Mage::getModel($this->getFrontendModel())
366: ->setAttribute($this);
367: }
368:
369: return $this->_frontend;
370: }
371:
372: 373: 374: 375: 376:
377: public function getSource()
378: {
379: if (empty($this->_source)) {
380: if (!$this->getSourceModel()) {
381: $this->setSourceModel($this->_getDefaultSourceModel());
382: }
383: $source = Mage::getModel($this->getSourceModel());
384: if (!$source) {
385: throw Mage::exception('Mage_Eav',
386: Mage::helper('eav')->__('Source model "%s" not found for attribute "%s"',$this->getSourceModel(), $this->getAttributeCode())
387: );
388: }
389: $this->_source = $source->setAttribute($this);
390: }
391: return $this->_source;
392: }
393:
394: public function usesSource()
395: {
396: return $this->getFrontendInput() === 'select' || $this->getFrontendInput() === 'multiselect'
397: || $this->getData('source_model') != '';
398: }
399:
400: protected function _getDefaultBackendModel()
401: {
402: return Mage_Eav_Model_Entity::DEFAULT_BACKEND_MODEL;
403: }
404:
405: protected function _getDefaultFrontendModel()
406: {
407: return Mage_Eav_Model_Entity::DEFAULT_FRONTEND_MODEL;
408: }
409:
410: protected function _getDefaultSourceModel()
411: {
412: return $this->getEntity()->getDefaultAttributeSourceModel();
413: }
414:
415: public function isValueEmpty($value)
416: {
417: $attrType = $this->getBackend()->getType();
418: $isEmpty = is_array($value)
419: || ($value === null)
420: || $value === false && $attrType != 'int'
421: || $value === '' && ($attrType == 'int' || $attrType == 'decimal' || $attrType == 'datetime');
422:
423: return $isEmpty;
424: }
425:
426: 427: 428: 429: 430: 431:
432: public function isInSet($setId)
433: {
434: if (!$this->hasAttributeSetInfo()) {
435: return true;
436: }
437:
438: if (is_array($setId)
439: && count(array_intersect($setId, array_keys($this->getAttributeSetInfo())))) {
440: return true;
441: }
442:
443: if (!is_array($setId)
444: && array_key_exists($setId, $this->getAttributeSetInfo())) {
445: return true;
446: }
447:
448: return false;
449: }
450:
451: 452: 453: 454: 455: 456: 457:
458: public function isInGroup($setId, $groupId)
459: {
460: $dataPath = sprintf('attribute_set_info/%s/group_id', $setId);
461: if ($this->isInSet($setId) && $this->getData($dataPath) == $groupId) {
462: return true;
463: }
464:
465: return false;
466: }
467:
468: 469: 470: 471: 472: 473: 474:
475: public function getIdByCode($entityType, $code)
476: {
477: $k = "{$entityType}|{$code}";
478: if (!isset($this->_attributeIdCache[$k])) {
479: $this->_attributeIdCache[$k] = $this->getResource()->getIdByCode($entityType, $code);
480: }
481: return $this->_attributeIdCache[$k];
482: }
483:
484: 485: 486: 487: 488:
489: public function isStatic()
490: {
491: return $this->getBackendType() == self::TYPE_STATIC || $this->getBackendType() == '';
492: }
493:
494: 495: 496: 497: 498:
499: public function getBackendTable()
500: {
501: if ($this->_dataTable === null) {
502: if ($this->isStatic()) {
503: $this->_dataTable = $this->getEntityType()->getValueTablePrefix();
504: } else {
505: $backendTable = trim($this->_getData('backend_table'));
506: if (empty($backendTable)) {
507: $entityTable = array($this->getEntity()->getEntityTablePrefix(), $this->getBackendType());
508: $backendTable = $this->getResource()->getTable($entityTable);
509: }
510: $this->_dataTable = $backendTable;
511: }
512: }
513: return $this->_dataTable;
514: }
515:
516: 517: 518: 519: 520:
521: public function getFlatColumns()
522: {
523:
524: if ($this->usesSource() && $this->getBackendType() != self::TYPE_STATIC) {
525: return $this->getSource()->getFlatColums();
526: }
527:
528: if (Mage::helper('core')->useDbCompatibleMode()) {
529: return $this->_getFlatColumnsOldDefinition();
530: } else {
531: return $this->_getFlatColumnsDdlDefinition();
532: }
533: }
534:
535: 536: 537: 538: 539:
540: public function _getFlatColumnsDdlDefinition()
541: {
542: $helper = Mage::getResourceHelper('eav');
543: $columns = array();
544: switch ($this->getBackendType()) {
545: case 'static':
546: $describe = $this->_getResource()->describeTable($this->getBackend()->getTable());
547: if (!isset($describe[$this->getAttributeCode()])) {
548: break;
549: }
550: $prop = $describe[$this->getAttributeCode()];
551: $type = $prop['DATA_TYPE'];
552: $size = ($prop['LENGTH'] ? $prop['LENGTH'] : null);
553:
554: $columns[$this->getAttributeCode()] = array(
555: 'type' => $helper->getDdlTypeByColumnType($type),
556: 'length' => $size,
557: 'unsigned' => $prop['UNSIGNED'] ? true: false,
558: 'nullable' => $prop['NULLABLE'],
559: 'default' => $prop['DEFAULT'],
560: 'extra' => null
561: );
562: break;
563: case 'datetime':
564: $columns[$this->getAttributeCode()] = array(
565: 'type' => Varien_Db_Ddl_Table::TYPE_DATETIME,
566: 'unsigned' => false,
567: 'nullable' => true,
568: 'default' => null,
569: 'extra' => null
570: );
571: break;
572: case 'decimal':
573: $columns[$this->getAttributeCode()] = array(
574: 'type' => Varien_Db_Ddl_Table::TYPE_DECIMAL,
575: 'length' => '12,4',
576: 'unsigned' => false,
577: 'nullable' => true,
578: 'default' => null,
579: 'extra' => null
580: );
581: break;
582: case 'int':
583: $columns[$this->getAttributeCode()] = array(
584: 'type' => Varien_Db_Ddl_Table::TYPE_INTEGER,
585: 'unsigned' => false,
586: 'nullable' => true,
587: 'default' => null,
588: 'extra' => null
589: );
590: break;
591: case 'text':
592: $columns[$this->getAttributeCode()] = array(
593: 'type' => Varien_Db_Ddl_Table::TYPE_TEXT,
594: 'unsigned' => false,
595: 'nullable' => true,
596: 'default' => null,
597: 'extra' => null,
598: 'length' => Varien_Db_Ddl_Table::MAX_TEXT_SIZE
599: );
600: break;
601: case 'varchar':
602: $columns[$this->getAttributeCode()] = array(
603: 'type' => Varien_Db_Ddl_Table::TYPE_TEXT,
604: 'length' => '255',
605: 'unsigned' => false,
606: 'nullable' => true,
607: 'default' => null,
608: 'extra' => null
609: );
610: break;
611: }
612:
613: return $columns;
614: }
615:
616: 617: 618: 619: 620: 621:
622: protected function _getFlatColumnsOldDefinition() {
623: $columns = array();
624: switch ($this->getBackendType()) {
625: case 'static':
626: $describe = $this->_getResource()->describeTable($this->getBackend()->getTable());
627: if (!isset($describe[$this->getAttributeCode()])) {
628: break;
629: }
630: $prop = $describe[$this->getAttributeCode()];
631: $columns[$this->getAttributeCode()] = array(
632: 'type' => $prop['DATA_TYPE'] . ($prop['LENGTH'] ? "({$prop['LENGTH']})" : ""),
633: 'unsigned' => $prop['UNSIGNED'] ? true: false,
634: 'is_null' => $prop['NULLABLE'],
635: 'default' => $prop['DEFAULT'],
636: 'extra' => null
637: );
638: break;
639: case 'datetime':
640: $columns[$this->getAttributeCode()] = array(
641: 'type' => 'datetime',
642: 'unsigned' => false,
643: 'is_null' => true,
644: 'default' => null,
645: 'extra' => null
646: );
647: break;
648: case 'decimal':
649: $columns[$this->getAttributeCode()] = array(
650: 'type' => 'decimal(12,4)',
651: 'unsigned' => false,
652: 'is_null' => true,
653: 'default' => null,
654: 'extra' => null
655: );
656: break;
657: case 'int':
658: $columns[$this->getAttributeCode()] = array(
659: 'type' => 'int',
660: 'unsigned' => false,
661: 'is_null' => true,
662: 'default' => null,
663: 'extra' => null
664: );
665: break;
666: case 'text':
667: $columns[$this->getAttributeCode()] = array(
668: 'type' => 'text',
669: 'unsigned' => false,
670: 'is_null' => true,
671: 'default' => null,
672: 'extra' => null
673: );
674: break;
675: case 'varchar':
676: $columns[$this->getAttributeCode()] = array(
677: 'type' => 'varchar(255)',
678: 'unsigned' => false,
679: 'is_null' => true,
680: 'default' => null,
681: 'extra' => null
682: );
683: break;
684: }
685: return $columns;
686: }
687:
688: 689: 690: 691: 692:
693: public function getFlatIndexes()
694: {
695: $condition = $this->getUsedForSortBy();
696: if ($this->getFlatAddFilterableAttributes()) {
697: $condition = $condition || $this->getIsFilterable();
698: }
699:
700: if ($condition) {
701: if ($this->usesSource() && $this->getBackendType() != self::TYPE_STATIC) {
702: return $this->getSource()->getFlatIndexes();
703: }
704: $indexes = array();
705:
706: switch ($this->getBackendType()) {
707: case 'static':
708: $describe = $this->_getResource()
709: ->describeTable($this->getBackend()->getTable());
710: if (!isset($describe[$this->getAttributeCode()])) {
711: break;
712: }
713: $indexDataTypes = array(
714: 'varchar',
715: 'varbinary',
716: 'char',
717: 'date',
718: 'datetime',
719: 'timestamp',
720: 'time',
721: 'year',
722: 'enum',
723: 'set',
724: 'bit',
725: 'bool',
726: 'tinyint',
727: 'smallint',
728: 'mediumint',
729: 'int',
730: 'bigint',
731: 'float',
732: 'double',
733: 'decimal',
734: );
735: $prop = $describe[$this->getAttributeCode()];
736: if (in_array($prop['DATA_TYPE'], $indexDataTypes)) {
737: $indexName = 'IDX_' . strtoupper($this->getAttributeCode());
738: $indexes[$indexName] = array(
739: 'type' => 'index',
740: 'fields' => array($this->getAttributeCode())
741: );
742: }
743:
744: break;
745: case 'datetime':
746: case 'decimal':
747: case 'int':
748: case 'varchar':
749: $indexName = 'IDX_' . strtoupper($this->getAttributeCode());
750: $indexes[$indexName] = array(
751: 'type' => 'index',
752: 'fields' => array($this->getAttributeCode())
753: );
754: break;
755: }
756:
757: return $indexes;
758: }
759:
760: return array();
761: }
762:
763: 764: 765: 766: 767: 768:
769: public function getFlatUpdateSelect($store = null) {
770: if ($store === null) {
771: foreach (Mage::app()->getStores() as $store) {
772: $this->getFlatUpdateSelect($store->getId());
773: }
774: return $this;
775: }
776:
777: if ($this->getBackendType() == self::TYPE_STATIC) {
778: return null;
779: }
780:
781: if ($this->usesSource()) {
782: return $this->getSource()->getFlatUpdateSelect($store);
783: }
784: return $this->_getResource()->getFlatUpdateSelect($this, $store);
785: }
786: }
787: