PageRenderTime 50ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Abstract.php

https://bitbucket.org/claudiu_marginean/magento-hg-mirror
PHP | 715 lines | 370 code | 49 blank | 296 comment | 69 complexity | 3395efdaf25d782acfc4058504b60b37 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, LGPL-2.1, GPL-2.0, WTFPL
  1. <?php
  2. /**
  3. * Magento
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@magentocommerce.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade Magento to newer
  18. * versions in the future. If you wish to customize Magento for your
  19. * needs please refer to http://www.magentocommerce.com for more information.
  20. *
  21. * @category Mage
  22. * @package Mage_Catalog
  23. * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. */
  26. /**
  27. * Catalog entity abstract model
  28. *
  29. * @category Mage
  30. * @package Mage_Catalog
  31. * @author Magento Core Team <core@magentocommerce.com>
  32. */
  33. abstract class Mage_Catalog_Model_Resource_Eav_Mysql4_Abstract extends Mage_Eav_Model_Entity_Abstract
  34. {
  35. /**
  36. * Store firstly set attributes to filter selected attributes when used specific store_id
  37. *
  38. * @var array
  39. */
  40. protected $_attributes = array();
  41. /**
  42. * Redeclare attribute model
  43. *
  44. * @return string
  45. */
  46. protected function _getDefaultAttributeModel()
  47. {
  48. return 'catalog/resource_eav_attribute';
  49. }
  50. public function getDefaultStoreId()
  51. {
  52. return Mage_Catalog_Model_Abstract::DEFAULT_STORE_ID;
  53. }
  54. /**
  55. * Check whether the attribute is Applicable to the object
  56. *
  57. * @param Varien_Object $object
  58. * @param Mage_Catalog_Model_Resource_Eav_Attribute $attribute
  59. * @return boolean
  60. */
  61. protected function _isApplicableAttribute ($object, $attribute)
  62. {
  63. $applyTo = $attribute->getApplyTo();
  64. return count($applyTo) == 0 || in_array($object->getTypeId(), $applyTo);
  65. }
  66. /**
  67. * Check whether attribute instance (attribute, backend, frontend or source) has method and applicable
  68. *
  69. * @param Mage_Eav_Model_Entity_Attribute_Abstract|Mage_Eav_Model_Entity_Attribute_Backend_Abstract|Mage_Eav_Model_Entity_Attribute_Frontend_Abstract|Mage_Eav_Model_Entity_Attribute_Source_Abstract $instance
  70. * @param string $method
  71. * @param array $args array of arguments
  72. * @return boolean
  73. */
  74. protected function _isCallableAttributeInstance($instance, $method, $args)
  75. {
  76. if ($instance instanceof Mage_Eav_Model_Entity_Attribute_Backend_Abstract
  77. && ($method == 'beforeSave' || $method = 'afterSave')
  78. ) {
  79. $attributeCode = $instance->getAttribute()->getAttributeCode();
  80. if (isset($args[0]) && $args[0] instanceof Varien_Object && $args[0]->getData($attributeCode) === false) {
  81. return false;
  82. }
  83. }
  84. return parent::_isCallableAttributeInstance($instance, $method, $args);
  85. }
  86. /**
  87. * Retrieve select object for loading entity attributes values
  88. *
  89. * Join attribute store value
  90. *
  91. * @param Varien_Object $object
  92. * @param mixed $rowId
  93. * @return Zend_Db_Select
  94. */
  95. protected function _getLoadAttributesSelect($object, $table)
  96. {
  97. /**
  98. * This condition is applicable for all cases when we was work in not single
  99. * store mode, customize some value per specific store view and than back
  100. * to single store mode. We should load correct values
  101. */
  102. if (Mage::app()->isSingleStoreMode()) {
  103. $storeId = Mage::app()->getStore(true)->getId();
  104. }
  105. else {
  106. $storeId = $object->getStoreId();
  107. }
  108. $setId = $object->getAttributeSetId();
  109. $storeIds = array($this->getDefaultStoreId());
  110. if ($storeId != $this->getDefaultStoreId()) {
  111. $storeIds[] = $storeId;
  112. }
  113. $select = $this->_getReadAdapter()->select()
  114. ->from(array('attr_table' => $table))
  115. ->where('attr_table.'.$this->getEntityIdField().'=?', $object->getId())
  116. ->where('attr_table.store_id IN (?)', $storeIds);
  117. if ($setId) {
  118. $select->join(
  119. array('set_table' => $this->getTable('eav/entity_attribute')),
  120. 'attr_table.attribute_id=set_table.attribute_id AND set_table.attribute_set_id=' . intval($setId),
  121. array()
  122. );
  123. }
  124. return $select;
  125. }
  126. /**
  127. * Prepare select object for loading entity attributes values
  128. *
  129. * @param array $selects
  130. * @return Zend_Db_Select
  131. */
  132. protected function _prepareLoadSelect(array $selects)
  133. {
  134. $select = parent::_prepareLoadSelect($selects);
  135. $select->order('store_id');
  136. return $select;
  137. }
  138. /**
  139. * Initialize attribute value for object
  140. *
  141. * @param Mage_Catalog_Model_Abstract $object
  142. * @param array $valueRow
  143. * @return Mage_Eav_Model_Entity_Abstract
  144. */
  145. protected function _setAttribteValue($object, $valueRow)
  146. {
  147. $attribute = $this->getAttribute($valueRow['attribute_id']);
  148. if ($attribute) {
  149. $attributeCode = $attribute->getAttributeCode();
  150. $isDefaultStore = $valueRow['store_id'] == $this->getDefaultStoreId();
  151. if (isset($this->_attributes[$valueRow['attribute_id']])) {
  152. if ($isDefaultStore) {
  153. $object->setAttributeDefaultValue($attributeCode, $valueRow['value']);
  154. }
  155. else {
  156. $object->setAttributeDefaultValue(
  157. $attributeCode,
  158. $this->_attributes[$valueRow['attribute_id']]['value']
  159. );
  160. }
  161. }
  162. else {
  163. $this->_attributes[$valueRow['attribute_id']] = $valueRow;
  164. }
  165. $value = $valueRow['value'];
  166. $valueId = $valueRow['value_id'];
  167. $object->setData($attributeCode, $value);
  168. if (!$isDefaultStore) {
  169. $object->setExistsStoreValueFlag($attributeCode);
  170. }
  171. $attribute->getBackend()->setValueId($valueId);
  172. }
  173. return $this;
  174. }
  175. /**
  176. * Insert or Update attribute data
  177. *
  178. * @param Mage_Catalog_Model_Abstract $object
  179. * @param Mage_Eav_Model_Entity_Attribute_Abstract $attribute
  180. * @param mixed $value
  181. * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Abstract
  182. */
  183. protected function _saveAttributeValue($object, $attribute, $value)
  184. {
  185. $write = $this->_getWriteAdapter();
  186. $storeId = Mage::app()->getStore($object->getStoreId())->getId();
  187. $table = $attribute->getBackend()->getTable();
  188. /**
  189. * If we work in single store mode all values should be saved just
  190. * for default store id
  191. * In this case we clear all not default values
  192. */
  193. if (Mage::app()->isSingleStoreMode()) {
  194. $storeId = $this->getDefaultStoreId();
  195. $write->delete($table, join(' AND ', array(
  196. $write->quoteInto('attribute_id=?', $attribute->getAttributeId()),
  197. $write->quoteInto('entity_id=?', $object->getEntityId()),
  198. $write->quoteInto('store_id<>?', $storeId)
  199. )));
  200. }
  201. $bind = array(
  202. 'entity_type_id' => $attribute->getEntityTypeId(),
  203. 'attribute_id' => $attribute->getAttributeId(),
  204. 'store_id' => $storeId,
  205. 'entity_id' => $object->getEntityId(),
  206. 'value' => $this->_prepareValueForSave($value, $attribute)
  207. );
  208. if ($attribute->isScopeStore()) {
  209. /**
  210. * Update attribute value for store
  211. */
  212. $this->_attributeValuesToSave[$table][] = $bind;
  213. } else if ($attribute->isScopeWebsite() && $storeId != $this->getDefaultStoreId()) {
  214. /**
  215. * Update attribute value for website
  216. */
  217. $storeIds = Mage::app()->getStore($storeId)->getWebsite()->getStoreIds(true);
  218. foreach ($storeIds as $storeId) {
  219. $bind['store_id'] = $storeId;
  220. $this->_attributeValuesToSave[$table][] = $bind;
  221. }
  222. } else {
  223. /**
  224. * Update global attribute value
  225. */
  226. $bind['store_id'] = $this->getDefaultStoreId();
  227. $this->_attributeValuesToSave[$table][] = $bind;
  228. }
  229. return $this;
  230. }
  231. /**
  232. * Insert entity attribute value
  233. *
  234. * @param Varien_Object $object
  235. * @param Mage_Eav_Model_Entity_Attribute_Abstract $attribute
  236. * @param mixed $value
  237. * @return Mage_Eav_Model_Entity_Abstract
  238. */
  239. protected function _insertAttribute($object, $attribute, $value)
  240. {
  241. /**
  242. * save required attributes in global scope every time if store id different from default
  243. */
  244. $storeId = Mage::app()->getStore($object->getStoreId())->getId();
  245. if ($attribute->getIsRequired() && $this->getDefaultStoreId() != $storeId) {
  246. $bind = array(
  247. 'entity_type_id' => $attribute->getEntityTypeId(),
  248. 'attribute_id' => $attribute->getAttributeId(),
  249. 'store_id' => $this->getDefaultStoreId(),
  250. 'entity_id' => $object->getEntityId(),
  251. 'value' => $this->_prepareValueForSave($value, $attribute)
  252. );
  253. $this->_getWriteAdapter()->select()->insertIgnoreFromSelect($attribute->getBackend()->getTable(), $bind);
  254. }
  255. return $this->_saveAttributeValue($object, $attribute, $value);
  256. // $entityIdField = $attribute->getBackend()->getEntityIdField();
  257. // $row = array(
  258. // $entityIdField => $object->getId(),
  259. // 'entity_type_id'=> $object->getEntityTypeId(),
  260. // 'attribute_id' => $attribute->getId(),
  261. // 'value' => $this->_prepareValueForSave($value, $attribute),
  262. // 'store_id' => $this->getDefaultStoreId()
  263. // );
  264. //
  265. // $fields = array();
  266. // $bind = array();
  267. // foreach ($row as $k => $v) {
  268. // $fields[] = $this->_getWriteAdapter()->quoteIdentifier($k);
  269. // $bind[':' . $k] = $v;
  270. // }
  271. //
  272. // $sql = sprintf('INSERT IGNORE INTO %s (%s) VALUES(%s)',
  273. // $this->_getWriteAdapter()->quoteIdentifier($attribute->getBackend()->getTable()),
  274. // implode(',', $fields),
  275. // implode(',', array_keys($bind)));
  276. //
  277. // $this->_getWriteAdapter()->query($sql, $bind);
  278. // if (!$lastId = $this->_getWriteAdapter()->lastInsertId()) {
  279. // $select = $this->_getReadAdapter()->select()
  280. // ->from($attribute->getBackend()->getTable(), 'value_id')
  281. // ->where($entityIdField . '=?', $row[$entityIdField])
  282. // ->where('entity_type_id=?', $row['entity_type_id'])
  283. // ->where('attribute_id=?', $row['attribute_id'])
  284. // ->where('store_id=?', $row['store_id']);
  285. // $lastId = $select->query()->fetchColumn();
  286. // }
  287. // if ($object->getStoreId() != $this->getDefaultStoreId()) {
  288. // $this->_updateAttribute($object, $attribute, $lastId, $value);
  289. // }
  290. // return $this;
  291. }
  292. /**
  293. * Update entity attribute value
  294. *
  295. * @param Varien_Object $object
  296. * @param Mage_Eav_Model_Entity_Attribute_Abstract $attribute
  297. * @param mixed $valueId
  298. * @param mixed $value
  299. * @return Mage_Eav_Model_Entity_Abstract
  300. */
  301. protected function _updateAttribute($object, $attribute, $valueId, $value)
  302. {
  303. return $this->_saveAttributeValue($object, $attribute, $value);
  304. //
  305. // /**
  306. // * If we work in single store mode all values should be saved just
  307. // * for default store id
  308. // * In this case we clear all not default values
  309. // */
  310. // if (Mage::app()->isSingleStoreMode()) {
  311. // $this->_getWriteAdapter()->delete(
  312. // $attribute->getBackend()->getTable(),
  313. // $this->_getWriteAdapter()->quoteInto('attribute_id=?', $attribute->getId()) .
  314. // $this->_getWriteAdapter()->quoteInto(' AND entity_id=?', $object->getId()) .
  315. // $this->_getWriteAdapter()->quoteInto(
  316. // ' AND store_id!=?',
  317. // Mage_Catalog_Model_Abstract::DEFAULT_STORE_ID
  318. // )
  319. // );
  320. // }
  321. //
  322. // /**
  323. // * Update attribute value for store
  324. // */
  325. // if ($attribute->isScopeStore()) {
  326. // $this->_updateAttributeForStore($object, $attribute, $value, $object->getStoreId());
  327. // }
  328. //
  329. // /**
  330. // * Update attribute value for website
  331. // */
  332. // elseif ($attribute->isScopeWebsite()) {
  333. // if ($object->getStoreId() == 0) {
  334. // $this->_updateAttributeForStore($object, $attribute, $value, $object->getStoreId());
  335. // } else {
  336. // if (is_array($object->getWebsiteStoreIds())) {
  337. // foreach ($object->getWebsiteStoreIds() as $storeId) {
  338. // $this->_updateAttributeForStore($object, $attribute, $value, $storeId);
  339. // }
  340. // }
  341. // }
  342. // }
  343. // else {
  344. // $this->_getWriteAdapter()->update($attribute->getBackend()->getTable(),
  345. // array('value' => $this->_prepareValueForSave($value, $attribute)),
  346. // 'value_id='.(int)$valueId
  347. // );
  348. // }
  349. // return $this;
  350. }
  351. /**
  352. * Update attribute value for specific store
  353. *
  354. * @param Mage_Catalog_Model_Abstract $object
  355. * @param object $attribute
  356. * @param mixed $value
  357. * @param int $storeId
  358. * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Abstract
  359. */
  360. protected function _updateAttributeForStore($object, $attribute, $value, $storeId)
  361. {
  362. $entityIdField = $attribute->getBackend()->getEntityIdField();
  363. $select = $this->_getWriteAdapter()->select()
  364. ->from($attribute->getBackend()->getTable(), 'value_id')
  365. ->where('entity_type_id=?', $object->getEntityTypeId())
  366. ->where("$entityIdField=?",$object->getId())
  367. ->where('store_id=?', $storeId)
  368. ->where('attribute_id=?', $attribute->getId());
  369. /**
  370. * When value for store exist
  371. */
  372. if ($valueId = $this->_getWriteAdapter()->fetchOne($select)) {
  373. $this->_getWriteAdapter()->update($attribute->getBackend()->getTable(),
  374. array('value' => $this->_prepareValueForSave($value, $attribute)),
  375. 'value_id='.$valueId
  376. );
  377. }
  378. else {
  379. $this->_getWriteAdapter()->insert($attribute->getBackend()->getTable(), array(
  380. $entityIdField => $object->getId(),
  381. 'entity_type_id'=> $object->getEntityTypeId(),
  382. 'attribute_id' => $attribute->getId(),
  383. 'value' => $this->_prepareValueForSave($value, $attribute),
  384. 'store_id' => $storeId
  385. ));
  386. }
  387. return $this;
  388. }
  389. /**
  390. * Delete entity attribute values
  391. *
  392. * @param Varien_Object $object
  393. * @param string $table
  394. * @param array $info
  395. * @return Varien_Object
  396. */
  397. protected function _deleteAttributes($object, $table, $info)
  398. {
  399. $entityIdField = $this->getEntityIdField();
  400. $globalValues = array();
  401. $websiteAttributes = array();
  402. $storeAttributes = array();
  403. /**
  404. * Separate attributes by scope
  405. */
  406. foreach ($info as $itemData) {
  407. $attribute = $this->getAttribute($itemData['attribute_id']);
  408. if ($attribute->isScopeStore()) {
  409. $storeAttributes[] = $itemData['attribute_id'];
  410. }
  411. elseif ($attribute->isScopeWebsite()) {
  412. $websiteAttributes[] = $itemData['attribute_id'];
  413. }
  414. else {
  415. $globalValues[] = $itemData['value_id'];
  416. }
  417. }
  418. /**
  419. * Delete global scope attributes
  420. */
  421. if (!empty($globalValues)) {
  422. $condition = $this->_getWriteAdapter()->quoteInto('value_id IN (?)', $globalValues);
  423. $this->_getWriteAdapter()->delete($table, $condition);
  424. }
  425. $condition = $this->_getWriteAdapter()->quoteInto("$entityIdField=?", $object->getId())
  426. . $this->_getWriteAdapter()->quoteInto(' AND entity_type_id=?', $object->getEntityTypeId());
  427. /**
  428. * Delete website scope attributes
  429. */
  430. if (!empty($websiteAttributes)) {
  431. $storeIds = $object->getWebsiteStoreIds();
  432. if (!empty($storeIds)) {
  433. $delCondition = $condition
  434. . $this->_getWriteAdapter()->quoteInto(' AND attribute_id IN(?)', $websiteAttributes)
  435. . $this->_getWriteAdapter()->quoteInto(' AND store_id IN(?)', $storeIds);
  436. $this->_getWriteAdapter()->delete($table, $delCondition);
  437. }
  438. }
  439. /**
  440. * Delete store scope attributes
  441. */
  442. if (!empty($storeAttributes)) {
  443. $delCondition = $condition
  444. . $this->_getWriteAdapter()->quoteInto(' AND attribute_id IN(?)', $storeAttributes)
  445. . $this->_getWriteAdapter()->quoteInto(' AND store_id =?', $object->getStoreId());
  446. $this->_getWriteAdapter()->delete($table, $delCondition);
  447. }
  448. return $this;
  449. }
  450. /**
  451. * Retrieve Object instance with original data
  452. *
  453. * @param Varien_Object $object
  454. * @return Varien_Object
  455. */
  456. protected function _getOrigObject($object)
  457. {
  458. $className = get_class($object);
  459. $origObject = new $className();
  460. $origObject->setData(array());
  461. $origObject->setStoreId($object->getStoreId());
  462. $this->load($origObject, $object->getData($this->getEntityIdField()));
  463. return $origObject;
  464. }
  465. protected function _collectOrigData($object)
  466. {
  467. $this->loadAllAttributes($object);
  468. if ($this->getUseDataSharing()) {
  469. $storeId = $object->getStoreId();
  470. } else {
  471. $storeId = $this->getStoreId();
  472. }
  473. $allStores = Mage::getConfig()->getStoresConfigByPath('system/store/id', array(), 'code');
  474. //echo "<pre>".print_r($allStores ,1)."</pre>"; exit;
  475. $data = array();
  476. foreach ($this->getAttributesByTable() as $table=>$attributes) {
  477. $entityIdField = current($attributes)->getBackend()->getEntityIdField();
  478. $select = $this->_getReadAdapter()->select()
  479. ->from($table)
  480. ->where($this->getEntityIdField()."=?", $object->getId());
  481. $where = $this->_getReadAdapter()->quoteInto("store_id=?", $storeId);
  482. $globalAttributeIds = array();
  483. foreach ($attributes as $attrCode=>$attr) {
  484. if ($attr->getIsGlobal()) {
  485. $globalAttributeIds[] = $attr->getId();
  486. }
  487. }
  488. if (!empty($globalAttributeIds)) {
  489. $where .= ' or '.$this->_getReadAdapter()->quoteInto('attribute_id in (?)', $globalAttributeIds);
  490. }
  491. $select->where($where);
  492. $values = $this->_getReadAdapter()->fetchAll($select);
  493. if (empty($values)) {
  494. continue;
  495. }
  496. foreach ($values as $row) {
  497. $data[$this->getAttribute($row['attribute_id'])->getName()][$row['store_id']] = $row;
  498. }
  499. foreach ($attributes as $attrCode=>$attr) {
  500. }
  501. }
  502. return $data;
  503. }
  504. /**
  505. * Check is attribute value empty
  506. *
  507. * @param Mage_Eav_Model_Entity_Attribute_Abstract $attribute
  508. * @param mixed $value
  509. * @return bool
  510. */
  511. protected function _isAttributeValueEmpty(Mage_Eav_Model_Entity_Attribute_Abstract $attribute, $value)
  512. {
  513. return $value === false;
  514. }
  515. /**
  516. * Return if attribute exists in original data array.
  517. * Checks also attribute's store scope:
  518. * We should insert on duplicate key update values if we unchecked 'STORE VIEW' checkbox in store view.
  519. *
  520. * @param Mage_Eav_Model_Entity_Attribute_Abstract $attribute
  521. * @param mixed $value New value of the attribute.
  522. * @param array $origData
  523. * @return bool
  524. */
  525. protected function _canUpdateAttribute(
  526. Mage_Eav_Model_Entity_Attribute_Abstract $attribute,
  527. $value,
  528. array &$origData)
  529. {
  530. $result = parent::_canUpdateAttribute($attribute, $value, $origData);
  531. if ($result &&
  532. ($attribute->isScopeStore() || $attribute->isScopeWebsite()) &&
  533. !$this->_isAttributeValueEmpty($attribute, $value) &&
  534. $value == $origData[$attribute->getAttributeCode()] &&
  535. isset($origData['store_id']) && $origData['store_id'] != $this->getDefaultStoreId()
  536. ) {
  537. return false;
  538. }
  539. return $result;
  540. }
  541. /**
  542. * Prepare value for save
  543. *
  544. * @param mixed $value
  545. * @param Mage_Eav_Model_Entity_Attribute_Abstract $attribute
  546. * @return mixed
  547. */
  548. protected function _prepareValueForSave($value, Mage_Eav_Model_Entity_Attribute_Abstract $attribute)
  549. {
  550. $type = $attribute->getBackendType();
  551. if (($type == 'int' || $type == 'decimal' || $type == 'datetime') && $value === '') {
  552. return null;
  553. }
  554. if ($type == 'decimal') {
  555. return Mage::app()->getLocale()->getNumber($value);
  556. }
  557. return $value;
  558. }
  559. /**
  560. * Retrieve attribute's raw value from DB.
  561. *
  562. * @param int $entityId
  563. * @param int|string|array $attribute atrribute's ids or codes
  564. * @param int|Mage_Core_Model_Store $store
  565. * @return bool|string|array
  566. */
  567. public function getAttributeRawValue($entityId, $attribute, $store)
  568. {
  569. if (!$entityId || empty($attribute)) {
  570. return false;
  571. }
  572. if (!is_array($attribute)) {
  573. $attribute = array($attribute);
  574. }
  575. $attributesData = array();
  576. $staticAttributes = array();
  577. $typedAttributes = array();
  578. $staticTable = null;
  579. foreach ($attribute as $_attribute) {
  580. /* @var $attribute Mage_Catalog_Model_Entity_Attribute */
  581. $_attribute = $this->getAttribute($_attribute);
  582. if (!$_attribute) {
  583. continue;
  584. }
  585. $attributeCode = $_attribute->getAttributeCode();
  586. $attrTable = $_attribute->getBackend()->getTable();
  587. $isStatic = $_attribute->getBackend()->isStatic();
  588. if ($isStatic) {
  589. $staticAttributes[] = $attributeCode;
  590. $staticTable = $attrTable;
  591. }
  592. else {
  593. /**
  594. * That structure needed to avoid farther sql joins for getting attribute's code by id
  595. */
  596. $typedAttributes[$attrTable][$_attribute->getId()] = $attributeCode;
  597. }
  598. }
  599. /* @var $select Zend_Db_Select */
  600. $select = $this->_getReadAdapter()->select();
  601. /**
  602. * Collecting static attributes
  603. */
  604. if ($staticAttributes) {
  605. $select->from($staticTable, $staticAttributes)
  606. ->where($this->getEntityIdField() . ' = ?', $entityId);
  607. $attributesData = $this->_getReadAdapter()->fetchRow($select);
  608. }
  609. /**
  610. * Collecting typed attributes, performing separate SQL query for each attribute type table
  611. */
  612. if ($store instanceof Mage_Core_Model_Store) {
  613. $store = $store->getId();
  614. }
  615. $store = (int)$store;
  616. if ($typedAttributes) {
  617. foreach ($typedAttributes as $table => $_attributes) {
  618. $select->reset()->from(array('default_value' => $table), array());
  619. $select->where('default_value.attribute_id IN (?)', array_keys($_attributes))
  620. ->where('default_value.entity_type_id = ? ', $this->getTypeId())
  621. ->where('default_value.entity_id = ? ', $entityId)
  622. ->where('default_value.store_id = 0');
  623. $joinCondition = $this->_getReadAdapter()->quoteInto(
  624. 'store_value.attribute_id IN (?)',
  625. array_keys($_attributes)
  626. );
  627. $joinCondition .= ' AND ' . $this->_getReadAdapter()->quoteInto(
  628. 'store_value.entity_type_id = ?',
  629. $this->getTypeId()
  630. );
  631. $joinCondition .= ' AND ' . $this->_getReadAdapter()->quoteInto('store_value.entity_id = ?', $entityId);
  632. $joinCondition .= ' AND ' . $this->_getReadAdapter()->quoteInto('store_value.store_id = ?', $store);
  633. $select->joinLeft(array('store_value' => $table),
  634. $joinCondition,
  635. array(
  636. 'attr_value' => 'IFNULL(store_value.value, default_value.value)',
  637. 'default_value.attribute_id'
  638. )
  639. );
  640. $result = $this->_getReadAdapter()->fetchAll($select);
  641. foreach ($result as $key => $_attribute) {
  642. $attributeCode = $typedAttributes[$table][$_attribute['attribute_id']];
  643. $attributesData[$attributeCode] = $_attribute['attr_value'];
  644. }
  645. }
  646. }
  647. if (sizeof($attributesData) == 1) {
  648. $_data = each($attributesData);
  649. $attributesData = $_data[1];
  650. }
  651. return $attributesData ? $attributesData : false;
  652. }
  653. /**
  654. * Reset firstly loaded attributes
  655. *
  656. * @param Varien_Object $object
  657. * @param integer $entityId
  658. * @param array|null $attributes
  659. * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Abstract
  660. */
  661. public function load($object, $entityId, $attributes=array())
  662. {
  663. $this->_attributes = array();
  664. return parent::load($object, $entityId, $attributes);
  665. }
  666. }