00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 class Mage_Eav_Model_Config
00029 {
00030 const ENTITIES_CACHE_ID = 'EAV_ENTITY_TYPES';
00031 const ATTRIBUTES_CACHE_ID = 'EAV_ENTITY_ATTRIBUTES';
00032
00033
00034
00035
00036
00037
00038 protected $_entityData;
00039
00040
00041
00042
00043
00044
00045 protected $_attributeData;
00046
00047
00048
00049
00050
00051
00052 protected $_preloadedAttributes = array();
00053
00054
00055
00056
00057
00058
00059 protected $_initializedAttributes = array();
00060
00061
00062
00063
00064
00065
00066 protected $_attributeCodes = array();
00067
00068
00069
00070
00071
00072
00073
00074
00075 protected $_objects;
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 protected $_references;
00088
00089
00090
00091
00092
00093
00094 protected $_isCacheEnabled = null;
00095
00096
00097
00098
00099
00100
00101 protected $_collectionAttributes = array();
00102
00103
00104
00105
00106
00107
00108
00109 public function clear()
00110 {
00111 $this->_entityData = null;
00112 $this->_attributeData = null;
00113 $this->_objects = null;
00114 $this->_references = null;
00115 $this->_preloadedAttributes = array();
00116 $this->_initializedAttributes = array();
00117 return $this;
00118 }
00119
00120
00121
00122
00123
00124
00125
00126 protected function _load($id)
00127 {
00128 return isset($this->_objects[$id]) ? $this->_objects[$id] : null;
00129 }
00130
00131
00132
00133
00134
00135
00136
00137
00138 protected function _save($obj, $id)
00139 {
00140 $this->_objects[$id] = $obj;
00141 return $this;
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151 protected function _addEntityTypeReference($id, $code)
00152 {
00153 $this->_references['entity'][$id] = $code;
00154 return $this;
00155 }
00156
00157
00158
00159
00160
00161
00162
00163 protected function _getEntityTypeReference($id)
00164 {
00165 return isset($this->_references['entity'][$id]) ? $this->_references['entity'][$id] : null;
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 protected function _addAttributeReference($id, $code, $entityTypeCode)
00177 {
00178 $this->_references['attribute'][$entityTypeCode][$id] = $code;
00179 return $this;
00180 }
00181
00182
00183
00184
00185
00186
00187
00188
00189 protected function _getAttributeReference($id, $entityTypeCode)
00190 {
00191 if (isset($this->_references['attribute'][$entityTypeCode][$id])) {
00192 return $this->_references['attribute'][$entityTypeCode][$id];
00193 }
00194 return null;
00195 }
00196
00197
00198
00199
00200
00201
00202
00203 protected function _getEntityKey($code)
00204 {
00205 return 'ENTITY/'.$code;
00206 }
00207
00208
00209
00210
00211
00212
00213
00214
00215 protected function _getAttributeKey($entityTypeCode, $attributeCode)
00216 {
00217 return 'ATTRIBUTE/'. $entityTypeCode .'/' . $attributeCode;
00218 }
00219
00220
00221
00222
00223
00224
00225 protected function _isCacheEnabled()
00226 {
00227 if ($this->_isCacheEnabled === null) {
00228 $this->_isCacheEnabled = Mage::app()->useCache('eav');
00229 }
00230 return $this->_isCacheEnabled;
00231 }
00232
00233
00234
00235
00236
00237
00238 protected function _initEntityTypes()
00239 {
00240 if (is_array($this->_entityData)) {
00241 return $this;
00242 }
00243 Varien_Profiler::start('EAV: '.__METHOD__);
00244
00245
00246
00247
00248 if ($this->_isCacheEnabled()
00249 && ($cache = Mage::app()->loadCache(self::ENTITIES_CACHE_ID))) {
00250
00251 $this->_entityData = unserialize($cache);
00252 foreach ($this->_entityData as $typeCode => $data) {
00253 $typeId = $data['entity_type_id'];
00254 $this->_addEntityTypeReference($typeId, $typeCode);
00255 }
00256 Varien_Profiler::stop('EAV: '.__METHOD__);
00257 return $this;
00258 }
00259
00260 $entityTypesData = Mage::getModel('eav/entity_type')->getCollection()->getData();
00261 $types = array();
00262
00263
00264
00265
00266 foreach ($entityTypesData as $typeData) {
00267 if (!isset($typeData['attribute_model'])) {
00268 $typeData['attribute_model'] = 'eav/entity_attribute';
00269 }
00270
00271 $typeCode = $typeData['entity_type_code'];
00272 $typeId = $typeData['entity_type_id'];
00273
00274 $this->_addEntityTypeReference($typeId, $typeCode);
00275 $types[$typeCode] = $typeData;
00276 }
00277
00278 $this->_entityData = $types;
00279
00280 if ($this->_isCacheEnabled()) {
00281 Mage::app()->saveCache(serialize($this->_entityData), self::ENTITIES_CACHE_ID,
00282 array('eav', Mage_Eav_Model_Entity_Attribute::CACHE_TAG)
00283 );
00284 }
00285 Varien_Profiler::stop('EAV: '.__METHOD__);
00286 return $this;
00287 }
00288
00289
00290
00291
00292
00293
00294
00295 public function getEntityType($code)
00296 {
00297 if ($code instanceof Mage_Eav_Model_Entity_Type) {
00298 return $code;
00299 }
00300 Varien_Profiler::start('EAV: '.__METHOD__);
00301
00302
00303 if (is_numeric($code)) {
00304 $entityCode = $this->_getEntityTypeReference($code);
00305 if ($entityCode !== null) {
00306 $code = $entityCode;
00307
00308 }
00309 }
00310
00311 $entityKey = $this->_getEntityKey($code);
00312 if ($entityType = $this->_load($entityKey)) {
00313 Varien_Profiler::stop('EAV: '.__METHOD__);
00314 return $entityType;
00315 }
00316
00317
00318 $entityType = Mage::getModel('eav/entity_type');
00319 if (isset($this->_entityData[$code])) {
00320 $entityType->setData($this->_entityData[$code]);
00321 }
00322 else {
00323 if (is_numeric($code)) {
00324 $entityType->load($code);
00325 } else {
00326 $entityType->loadByCode($code);
00327 }
00328
00329 if (!$entityType->getId()) {
00330 Mage::throwException(Mage::helper('eav')->__('Invalid entity_type specified: %s', $code));
00331 }
00332 }
00333 $this->_addEntityTypeReference($entityType->getId(), $entityType->getEntityTypeCode());
00334 $this->_save($entityType, $entityKey);
00335
00336 Varien_Profiler::stop('EAV: '.__METHOD__);
00337 return $entityType;
00338 }
00339
00340
00341
00342
00343
00344
00345
00346 protected function _initAttributes($entityType)
00347 {
00348 $entityType = $this->getEntityType($entityType);
00349 $entityTypeCode = $entityType->getEntityTypeCode();
00350
00351 if (isset($this->_initializedAttributes[$entityTypeCode])) {
00352 return $this;
00353 }
00354 Varien_Profiler::start('EAV: '.__METHOD__);
00355
00356 $attributesInfo = Mage::getResourceModel('eav/entity_attribute_collection')
00357 ->setEntityTypeFilter($entityType->getId())
00358
00359 ->getData();
00360
00361 $codes = array();
00362 foreach ($attributesInfo as $attribute) {
00363 $this->_createAttribute($entityType, $attribute);
00364 $codes[] = $attribute['attribute_code'];
00365 }
00366
00367 $entityType->setAttributeCodes($codes);
00368 $this->_initializedAttributes[$entityTypeCode] = true;
00369
00370 Varien_Profiler::stop('EAV: '.__METHOD__);
00371 return $this;
00372 }
00373
00374
00375
00376
00377
00378
00379
00380
00381 public function getAttribute($entityType, $code)
00382 {
00383 if ($code instanceof Mage_Eav_Model_Entity_Attribute_Interface) {
00384 return $code;
00385 }
00386
00387 Varien_Profiler::start('EAV: '.__METHOD__);
00388
00389 $entityTypeCode = $this->getEntityType($entityType)->getEntityTypeCode();
00390 $entityType = $this->getEntityType($entityType);
00391
00392
00393
00394
00395 if (is_numeric($code)) {
00396 $attributeCode = $this->_getAttributeReference($code, $entityTypeCode);
00397 if ($attributeCode) {
00398 $code = $attributeCode;
00399 }
00400 }
00401 $attributeKey = $this->_getAttributeKey($entityTypeCode, $code);
00402
00403
00404
00405
00406 if ($attribute = $this->_load($attributeKey)) {
00407 Varien_Profiler::stop('EAV: '.__METHOD__);
00408 return $attribute;
00409 }
00410
00411
00412
00413
00414
00415
00416 $attribute = false;
00417 if (isset($this->_attributeData[$entityTypeCode][$code])) {
00418 $data = $this->_attributeData[$entityTypeCode][$code];
00419 unset($this->_attributeData[$entityTypeCode][$code]);
00420 $attribute = Mage::getModel($data['attribute_model'], $data);
00421 }
00422 else {
00423 if (is_numeric($code)) {
00424 $attribute = Mage::getModel($entityType->getAttributeModel())->load($code);
00425 if ($attribute->getEntityTypeId() != $entityType->getId()) {
00426 return false;
00427 }
00428 $attributeKey = $this->_getAttributeKey($entityTypeCode, $attribute->getAttributeCode());
00429 } else {
00430 $attribute = Mage::getModel($entityType->getAttributeModel())->loadByCode($entityType, $code);
00431 }
00432 }
00433
00434 if ($attribute) {
00435 $attribute->setEntityType($entityType);
00436 $this->_addAttributeReference($attribute->getId(), $attribute->getAttributeCode(), $entityTypeCode);
00437 $this->_save($attribute, $attributeKey);
00438 }
00439 Varien_Profiler::stop('EAV: '.__METHOD__);
00440 return $attribute;
00441 }
00442
00443
00444
00445
00446
00447
00448
00449
00450 public function getEntityAttributeCodes($entityType, $object=null)
00451 {
00452 $entityType = $this->getEntityType($entityType);
00453 $attributeSetId = 0;
00454 if (($object instanceof Varien_Object) && $object->getAttributeSetId()) {
00455 $attributeSetId = $object->getAttributeSetId();
00456 }
00457 $cacheKey = sprintf('%d-%d', $entityType->getId(), $attributeSetId);
00458 if (isset($this->_attributeCodes[$cacheKey])) {
00459 return $this->_attributeCodes[$cacheKey];
00460 }
00461
00462 if ($attributeSetId) {
00463
00464 $attributesInfo = Mage::getResourceModel('eav/entity_attribute_collection')
00465 ->setEntityTypeFilter($entityType->getId())
00466 ->setAttributeSetFilter($attributeSetId)
00467
00468 ->getData();
00469 $attributes = array();
00470 foreach ($attributesInfo as $attributeData) {
00471 $attributes[] = $attributeData['attribute_code'];
00472 $this->_createAttribute($entityType, $attributeData);
00473 }
00474 }
00475 else {
00476 $this->_initAttributes($entityType);
00477 $attributes = $this->getEntityType($entityType)->getAttributeCodes();
00478 }
00479
00480 $this->_attributeCodes[$cacheKey] = $attributes;
00481 return $attributes;
00482 }
00483
00484
00485
00486
00487
00488
00489
00490
00491 public function preloadAttributes($entityType, $attributes)
00492 {
00493 if (is_string($attributes)) {
00494 $attributes = array($attributes);
00495 }
00496
00497 $entityType = $this->getEntityType($entityType);
00498 $entityTypeCode = $entityType->getEntityTypeCode();
00499
00500 if (!isset($this->_preloadedAttributes[$entityTypeCode])) {
00501 $this->_preloadedAttributes[$entityTypeCode] = $attributes;
00502 }
00503 else {
00504 $attributes = array_diff($attributes, $this->_preloadedAttributes[$entityTypeCode]);
00505 $this->_preloadedAttributes[$entityTypeCode] = array_merge($this->_preloadedAttributes[$entityTypeCode], $attributes);
00506 }
00507
00508 if (empty($attributes)) {
00509 return $this;
00510 }
00511 Varien_Profiler::start('EAV: '.__METHOD__ . ':'.$entityTypeCode);
00512
00513 $attributesInfo = Mage::getResourceModel('eav/entity_attribute_collection')
00514 ->setEntityTypeFilter($entityType->getId())
00515 ->setCodeFilter($attributes)
00516
00517 ->getData();
00518
00519 if (!$attributesInfo) {
00520 Varien_Profiler::stop('EAV: '.__METHOD__ . ':'.$entityTypeCode);
00521 return $this;
00522 }
00523
00524 $attributesData = array();
00525 $codes = array();
00526
00527 foreach ($attributesInfo as $attribute) {
00528 if (!isset($attribute['attribute_model'])) {
00529 $attribute['attribute_model'] = $entityType->getAttributeModel();
00530 }
00531
00532 $attributeCode = $attribute['attribute_code'];
00533 $attributeId = $attribute['attribute_id'];
00534
00535 $this->_addAttributeReference($attributeId, $attributeCode, $entityTypeCode);
00536 $attributesData[$attributeCode] = $attribute;
00537 $codes[] = $attributeCode;
00538 }
00539
00540 $this->_attributeData[$entityTypeCode] = $attributesData;
00541
00542 Varien_Profiler::stop('EAV: '.__METHOD__ . ':'.$entityTypeCode);
00543 return $this;
00544 }
00545
00546
00547
00548
00549
00550
00551
00552
00553 public function getCollectionAttribute($entityType, $attribute)
00554 {
00555 $entityType = $this->getEntityType($entityType);
00556 $entityTypeCode = $entityType->getEntityTypeCode();
00557
00558 if (is_numeric($attribute)) {
00559 $attribute = $this->_getAttributeReference($attribute, $entityTypeCode);
00560 if (!$attribute) {
00561 return null;
00562 }
00563 }
00564
00565 $attributeKey = $this->_getAttributeKey($entityTypeCode, $attribute);
00566 if ($attributeObject = $this->_load($attributeKey)) {
00567 return $attributeObject;
00568 }
00569
00570 return $this->getAttribute($entityType, $attribute);
00571 }
00572
00573
00574
00575
00576
00577
00578
00579
00580 public function loadCollectionAttributes($entityType, $attributes)
00581 {
00582 $entityType = $this->getEntityType($entityType);
00583 $entityTypeCode = $entityType->getEntityTypeCode();
00584
00585 if (!isset($this->_collectionAttributes[$entityTypeCode])) {
00586 $this->_collectionAttributes[$entityTypeCode] = array();
00587 }
00588 $loadedAttributes = array_keys($this->_collectionAttributes[$entityTypeCode]);
00589 $attributes = array_diff($attributes, $loadedAttributes);
00590
00591 foreach ($attributes as $k => $attribute) {
00592 if (is_numeric($attribute)) {
00593 $attribute = $this->_getAttributeReference($attribute, $entityTypeCode);
00594 }
00595 $attributeKey = $this->_getAttributeKey($entityTypeCode, $attribute);
00596 if ($this->_load($attributeKey)) {
00597 unset($attributes[$k]);
00598 }
00599 }
00600
00601 if (empty($attributes)) {
00602 return $this;
00603 }
00604
00605 $attributesInfo = Mage::getResourceModel('eav/entity_attribute_collection')
00606 ->useLoadDataFields()
00607 ->setEntityTypeFilter($entityType->getId())
00608 ->setCodeFilter($attributes)
00609 ->getData();
00610
00611 foreach ($attributesInfo as $attributeData) {
00612 $attribute = $this->_createAttribute($entityType, $attributeData);
00613 $this->_collectionAttributes[$entityTypeCode][$attribute->getAttributeCode()] =$attribute;
00614 }
00615
00616 return $this;
00617 }
00618
00619
00620
00621
00622
00623
00624
00625
00626 protected function _createAttribute($entityType, $attributeData)
00627 {
00628 $entityType = $this->getEntityType($entityType);
00629 $entityTypeCode = $entityType->getEntityTypeCode();
00630
00631 $attributeKey = $this->_getAttributeKey($entityTypeCode, $attributeData['attribute_code']);
00632 if (($attribute = $this->_load($attributeKey))) {
00633 $existsFullAttribute = $attribute->hasIsRequired();
00634 $fullAttributeData = array_key_exists('is_required', $attributeData);
00635
00636 if ($existsFullAttribute || (!$existsFullAttribute && !$fullAttributeData)) {
00637 return $attribute;
00638 }
00639 }
00640
00641 if (isset($attributeData['attribute_model'])) {
00642 $model = $attributeData['attribute_model'];
00643 }
00644 else {
00645 $model = $entityType->getAttributeModel();
00646 }
00647 $attribute = Mage::getModel($model)->setData($attributeData);
00648 $this->_addAttributeReference(
00649 $attributeData['attribute_id'],
00650 $attributeData['attribute_code'],
00651 $entityTypeCode
00652 );
00653 $attributeKey = $this->_getAttributeKey($entityTypeCode, $attributeData['attribute_code']);
00654 $this->_save($attribute, $attributeKey);
00655 return $attribute;
00656 }
00657
00658
00659
00660
00661
00662
00663
00664 protected function _validateAttributeData($attributeData = null)
00665 {
00666 if (!is_array($attributeData)) {
00667 return false;
00668 }
00669 $requiredKeys = array(
00670 'attribute_id',
00671 'attribute_code',
00672 'entity_type_id',
00673 'attribute_model'
00674 );
00675 foreach ($requiredKeys as $key) {
00676 if (!array_key_exists($key, $attributeData)) {
00677 return false;
00678 }
00679 }
00680
00681 return true;
00682 }
00683
00684
00685
00686
00687
00688
00689
00690
00691 public function importAttributesData($entityType, array $attributes)
00692 {
00693 $entityType = $this->getEntityType($entityType);
00694 foreach ($attributes as $attributeData) {
00695 if (!$this->_validateAttributeData($attributeData)) {
00696 continue;
00697 }
00698 $this->_createAttribute($entityType, $attributeData);
00699 }
00700
00701 return $this;
00702 }
00703 }