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
00029
00030
00031
00032
00033
00034 class Mage_Catalog_Model_Resource_Eav_Mysql4_Product extends Mage_Catalog_Model_Resource_Eav_Mysql4_Abstract
00035 {
00036 protected $_productWebsiteTable;
00037 protected $_productCategoryTable;
00038
00039
00040
00041
00042 public function __construct()
00043 {
00044 parent::__construct();
00045 $resource = Mage::getSingleton('core/resource');
00046 $this->setType('catalog_product')
00047 ->setConnection(
00048 $resource->getConnection('catalog_read'),
00049 $resource->getConnection('catalog_write')
00050 );
00051
00052 $this->_productWebsiteTable = $resource->getTableName('catalog/product_website');
00053 $this->_productCategoryTable= $resource->getTableName('catalog/category_product');
00054 }
00055
00056
00057
00058
00059
00060
00061 protected function _getDefaultAttributes()
00062 {
00063 return array('entity_id', 'entity_type_id', 'attribute_set_id', 'type_id', 'created_at', 'updated_at');
00064 }
00065
00066
00067
00068
00069
00070
00071
00072 public function getWebsiteIds($product)
00073 {
00074 $select = $this->_getWriteAdapter()->select()
00075 ->from($this->_productWebsiteTable, 'website_id')
00076 ->where('product_id=?', $product->getId());
00077 return $this->_getWriteAdapter()->fetchCol($select);
00078 }
00079
00080
00081
00082
00083
00084
00085
00086 public function getCategoryIds($product)
00087 {
00088 $select = $this->_getWriteAdapter()->select()
00089 ->from($this->_productCategoryTable, 'category_id')
00090 ->where('product_id=?', $product->getId());
00091 return $this->_getWriteAdapter()->fetchCol($select);
00092 }
00093
00094
00095
00096
00097
00098
00099
00100 public function getIdBySku($sku)
00101 {
00102 return $this->_read->fetchOne('select entity_id from '.$this->getEntityTable().' where sku=?', $sku);
00103 }
00104
00105
00106
00107
00108
00109
00110
00111 protected function _beforeSave(Varien_Object $object)
00112 {
00113 if (!$object->getId() && $object->getSku()) {
00114 $object->setId($this->getIdBySku($object->getSku()));
00115 }
00116
00117 $categoryIds = $object->getCategoryIds();
00118 if ($categoryIds) {
00119 $categoryIds = Mage::getModel('catalog/category')->verifyIds($categoryIds);
00120 }
00121
00122 $object->setData('category_ids', implode(',', $categoryIds));
00123 return parent::_beforeSave($object);
00124 }
00125
00126
00127
00128
00129
00130
00131
00132 protected function _afterSave(Varien_Object $product)
00133 {
00134 $this->_saveWebsiteIds($product)
00135 ->_saveCategories($product)
00136 ->refreshIndex($product);
00137
00138 parent::_afterSave($product);
00139 return $this;
00140 }
00141
00142
00143
00144
00145
00146
00147
00148 protected function _saveWebsiteIds($product)
00149 {
00150 $websiteIds = $product->getWebsiteIds();
00151 $oldWebsiteIds = array();
00152
00153 $product->setIsChangedWebsites(false);
00154
00155 $select = $this->_getWriteAdapter()->select()
00156 ->from($this->_productWebsiteTable)
00157 ->where('product_id=?', $product->getId());
00158 $query = $this->_getWriteAdapter()->query($select);
00159 while ($row = $query->fetch()) {
00160 $oldWebsiteIds[] = $row['website_id'];
00161 }
00162
00163 $insert = array_diff($websiteIds, $oldWebsiteIds);
00164 $delete = array_diff($oldWebsiteIds, $websiteIds);
00165
00166 if (!empty($insert)) {
00167 foreach ($insert as $websiteId) {
00168 $this->_getWriteAdapter()->insert($this->_productWebsiteTable, array(
00169 'product_id' => $product->getId(),
00170 'website_id' => $websiteId
00171 ));
00172 }
00173 }
00174
00175 if (!empty($delete)) {
00176 foreach ($delete as $websiteId) {
00177 $this->_getWriteAdapter()->delete($this->_productWebsiteTable, array(
00178 $this->_getWriteAdapter()->quoteInto('product_id=?', $product->getId()),
00179 $this->_getWriteAdapter()->quoteInto('website_id=?', $websiteId)
00180 ));
00181 }
00182 }
00183
00184 if (!empty($insert) || !empty($delete)) {
00185 $product->setIsChangedWebsites(true);
00186 }
00187
00188 return $this;
00189 }
00190
00191
00192
00193
00194
00195
00196
00197 protected function _saveCategories(Varien_Object $object)
00198 {
00199 $categoryIds = $object->getCategoryIds();
00200
00201 $oldCategoryIds = $object->getOrigData('category_ids');
00202 $oldCategoryIds = !empty($oldCategoryIds) ? explode(',', $oldCategoryIds) : array();
00203
00204 $object->setIsChangedCategories(false);
00205
00206 $insert = array_diff($categoryIds, $oldCategoryIds);
00207 $delete = array_diff($oldCategoryIds, $categoryIds);
00208
00209 $write = $this->_getWriteAdapter();
00210 if (!empty($insert)) {
00211 $insertSql = array();
00212 foreach ($insert as $v) {
00213 if (!empty($v)) {
00214 $insertSql[] = '('.(int)$v.','.$object->getId().',0)';
00215 }
00216 };
00217 if ($insertSql) {
00218 $write->query("insert into {$this->_productCategoryTable}
00219 (category_id, product_id, position) values ".join(',', $insertSql));
00220 }
00221 }
00222
00223 if (!empty($delete)) {
00224 $write->delete($this->_productCategoryTable,
00225 $write->quoteInto('product_id=?', $object->getId())
00226 .' and '.$write->quoteInto('category_id in (?)', $delete)
00227 );
00228 }
00229
00230 if (!empty($insert) || !empty($delete)) {
00231 $object->setIsChangedCategories(true);
00232 }
00233
00234 return $this;
00235 }
00236
00237 public function refreshIndex($product)
00238 {
00239
00240
00241
00242 $categoryIds = $product->getCategoryIds();
00243
00244
00245
00246
00247 $this->_getWriteAdapter()->delete(
00248 $this->getTable('catalog/category_product_index'),
00249 $this->_getWriteAdapter()->quoteInto('product_id=?', $product->getId())
00250 );
00251
00252 if (!empty($categoryIds)) {
00253 $categoriesSelect = $this->_getWriteAdapter()->select()
00254 ->from($this->getTable('catalog/category'))
00255 ->where('entity_id IN (?)', $categoryIds);
00256 $categoriesInfo = $this->_getWriteAdapter()->fetchAll($categoriesSelect);
00257
00258
00259 $indexCategoryIds = array();
00260 foreach ($categoriesInfo as $categoryInfo) {
00261 $ids = explode('/', $categoryInfo['path']);
00262 $ids[] = $categoryInfo['entity_id'];
00263 $indexCategoryIds = array_merge($indexCategoryIds, $ids);
00264 }
00265
00266 $indexCategoryIds = array_unique($indexCategoryIds);
00267 $indexProductIds = array($product->getId());
00268 Mage::getResourceSingleton('catalog/category')->refreshProductIndex($indexCategoryIds, $indexProductIds);
00269 }
00270
00271
00272
00273
00274 $this->refreshEnabledIndex(null, $product);
00275 return $this;
00276 }
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 public function refreshEnabledIndex($store=null, $product=null)
00288 {
00289 $statusAttribute = $this->getAttribute('status');
00290 $visibilityAttribute = $this->getAttribute('visibility');
00291 $statusAttributeId = $statusAttribute->getId();
00292 $visibilityAttributeId = $visibilityAttribute->getId();
00293 $statusTable = $statusAttribute->getBackend()->getTable();
00294 $visibilityTable = $visibilityAttribute->getBackend()->getTable();
00295
00296 $indexTable = $this->getTable('catalog/product_enabled_index');
00297 if (is_null($store) && is_null($product)) {
00298 Mage::throwException(
00299 Mage::helper('catalog')->__('For reindex enabled product(s) you need specify store or product')
00300 );
00301 } elseif (is_null($product) || is_array($product)) {
00302 $storeId = $store->getId();
00303 $websiteId = $store->getWebsiteId();
00304
00305 $productsCondition = '';
00306 $deleteCondition = '';
00307 if (is_array($product) && !empty($product)) {
00308 $productsCondition = $this->_getWriteAdapter()->quoteInto(
00309 ' AND t_v_default.entity_id IN (?)',
00310 $product
00311 );
00312 $deleteCondition = $this->_getWriteAdapter()->quoteInto(' AND product_id IN (?)', $product);
00313 }
00314 $this->_getWriteAdapter()->delete($indexTable, 'store_id='.$storeId.$deleteCondition);
00315 $query = "INSERT INTO $indexTable
00316 SELECT
00317 t_v_default.entity_id, {$storeId}, IFNULL(t_v.value, t_v_default.value)
00318 FROM
00319 {$visibilityTable} AS t_v_default
00320 INNER JOIN {$this->getTable('catalog/product_website')} AS w
00321 ON w.product_id=t_v_default.entity_id AND w.website_id={$websiteId}
00322 LEFT JOIN {$visibilityTable} AS `t_v`
00323 ON (t_v.entity_id = t_v_default.entity_id)
00324 AND (t_v.attribute_id='{$visibilityAttributeId}')
00325 AND (t_v.store_id='{$storeId}')
00326 INNER JOIN {$statusTable} AS `t_s_default`
00327 ON (t_s_default.entity_id = t_v_default.entity_id)
00328 AND (t_s_default.attribute_id='{$statusAttributeId}')
00329 AND t_s_default.store_id=0
00330 LEFT JOIN {$statusTable} AS `t_s`
00331 ON (t_s.entity_id = t_v_default.entity_id)
00332 AND (t_s.attribute_id='{$statusAttributeId}')
00333 AND (t_s.store_id='{$storeId}')
00334 WHERE
00335 t_v_default.attribute_id='{$visibilityAttributeId}'
00336 AND t_v_default.store_id=0{$productsCondition}
00337 AND (IFNULL(t_s.value, t_s_default.value)=".Mage_Catalog_Model_Product_Status::STATUS_ENABLED.")";
00338 $this->_getWriteAdapter()->query($query);
00339 }
00340 elseif (is_null($store)) {
00341 foreach ($product->getStoreIds() as $storeId) {
00342 $store = Mage::app()->getStore($storeId);
00343 $this->refreshEnabledIndex($store, $product);
00344 }
00345 }
00346 else {
00347 $productId = $product->getId();
00348 $storeId = $store->getId();
00349 $this->_getWriteAdapter()->delete($indexTable, 'product_id='.$productId.' AND store_id='.$storeId);
00350 $query = "INSERT INTO $indexTable
00351 SELECT
00352 {$productId}, {$storeId}, IFNULL(t_v.value, t_v_default.value)
00353 FROM
00354 {$visibilityTable} AS t_v_default
00355 LEFT JOIN {$visibilityTable} AS `t_v`
00356 ON (t_v.entity_id = t_v_default.entity_id)
00357 AND (t_v.attribute_id='{$visibilityAttributeId}')
00358 AND (t_v.store_id='{$storeId}')
00359 INNER JOIN {$statusTable} AS `t_s_default`
00360 ON (t_s_default.entity_id = t_v_default.entity_id)
00361 AND (t_s_default.attribute_id='{$statusAttributeId}')
00362 AND t_s_default.store_id=0
00363 LEFT JOIN {$statusTable} AS `t_s`
00364 ON (t_s.entity_id = t_v_default.entity_id)
00365 AND (t_s.attribute_id='{$statusAttributeId}')
00366 AND (t_s.store_id='{$storeId}')
00367 WHERE
00368 t_v_default.entity_id={$productId}
00369 AND t_v_default.attribute_id='{$visibilityAttributeId}' AND t_v_default.store_id=0
00370 AND (IFNULL(t_s.value, t_s_default.value)=".Mage_Catalog_Model_Product_Status::STATUS_ENABLED.")";
00371 $this->_getWriteAdapter()->query($query);
00372 }
00373
00374 return $this;
00375 }
00376
00377
00378
00379
00380
00381
00382
00383 public function getCategoryCollection($product)
00384 {
00385 $collection = Mage::getResourceModel('catalog/category_collection')
00386 ->joinField('product_id',
00387 'catalog/category_product',
00388 'product_id',
00389 'category_id=entity_id',
00390 null)
00391 ->addFieldToFilter('product_id', (int) $product->getId());
00392 return $collection;
00393 }
00394
00395
00396
00397
00398
00399
00400 public function getDefaultAttributeSourceModel()
00401 {
00402 return 'eav/entity_attribute_source_table';
00403 }
00404
00405
00406
00407
00408
00409
00410
00411 public function validate($object)
00412 {
00413 parent::validate($object);
00414 return $this;
00415 }
00416
00417
00418
00419
00420
00421
00422
00423 public function canBeShowInCategory($product, $categoryId)
00424 {
00425 $select = $this->_getReadAdapter()->select()
00426 ->from($this->getTable('catalog/category_product_index'), 'product_id')
00427 ->where('product_id=?', $product->getId())
00428 ->where('category_id=?', $categoryId);
00429 return $this->_getReadAdapter()->fetchOne($select);
00430 }
00431
00432
00433
00434
00435
00436
00437
00438
00439 public function duplicate($oldId, $newId)
00440 {
00441 $eavTables = array('datetime', 'decimal', 'int', 'text', 'varchar');
00442
00443
00444 foreach ($eavTables as $suffix) {
00445 $tableName = $this->getTable('catalog_product_entity_' . $suffix);
00446 $sql = 'REPLACE INTO `' . $tableName . '` '
00447 . 'SELECT NULL, `entity_type_id`, `attribute_id`, `store_id`, ' . $newId . ', `value`'
00448 . 'FROM `' . $tableName . '` WHERE `entity_id`=' . $oldId . ' AND `store_id`>0';
00449 $this->_getWriteAdapter()->query($sql);
00450 }
00451
00452 return $this;
00453 }
00454
00455 public function getParentProductIds($object)
00456 {
00457 $childId = $object->getId();
00458
00459 $groupedProductsTable = $this->getTable('catalog/product_link');
00460 $groupedLinkTypeId = Mage_Catalog_Model_Product_Link::LINK_TYPE_GROUPED;
00461
00462 $configurableProductsTable = $this->getTable('catalog/product_super_link');
00463
00464 $groupedSelect = $this->_getReadAdapter()->select()
00465 ->from(array('g'=>$groupedProductsTable), 'g.product_id')
00466 ->where("g.linked_product_id = ?", $childId)
00467 ->where("link_type_id = ?", $groupedLinkTypeId);
00468
00469 $groupedIds = $this->_getReadAdapter()->fetchCol($groupedSelect);
00470
00471 $configurableSelect = $this->_getReadAdapter()->select()
00472 ->from(array('c'=>$configurableProductsTable), 'c.parent_id')
00473 ->where("c.product_id = ?", $childId);
00474
00475 $configurableIds = $this->_getReadAdapter()->fetchCol($configurableSelect);
00476 return array_merge($groupedIds, $configurableIds);
00477 }
00478 }