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_Catalog_Model_Convert_Adapter_Product
00029 extends Mage_Eav_Model_Convert_Adapter_Entity
00030 {
00031 const MULTI_DELIMITER = ' , ';
00032
00033
00034
00035
00036
00037
00038 protected $_productModel;
00039
00040
00041
00042
00043
00044
00045 protected $_productTypes;
00046
00047
00048
00049
00050
00051
00052 protected $_productTypeInstances = array();
00053
00054
00055
00056
00057
00058
00059 protected $_productAttributeSets;
00060
00061 protected $_stores;
00062
00063 protected $_attributes = array();
00064
00065 protected $_configs = array();
00066
00067 protected $_requiredFields = array();
00068
00069 protected $_ignoreFields = array();
00070
00071 protected $_imageFields = array();
00072
00073
00074
00075
00076
00077
00078 protected $_inventoryFields = array();
00079
00080
00081
00082
00083
00084
00085 protected $_inventoryFieldsProductTypes = array();
00086
00087 protected $_toNumber = array();
00088
00089
00090
00091
00092
00093 public function load()
00094 {
00095 $attrFilterArray = array();
00096 $attrFilterArray ['name'] = 'like';
00097 $attrFilterArray ['sku'] = 'like';
00098 $attrFilterArray ['type'] = 'eq';
00099 $attrFilterArray ['attribute_set'] = 'eq';
00100 $attrFilterArray ['visibility'] = 'eq';
00101 $attrFilterArray ['status'] = 'eq';
00102 $attrFilterArray ['price'] = 'fromTo';
00103 $attrFilterArray ['qty'] = 'fromTo';
00104 $attrFilterArray ['store_id'] = 'eq';
00105
00106 $attrToDb = array(
00107 'type' => 'type_id',
00108 'attribute_set' => 'attribute_set_id'
00109 );
00110
00111 $filters = $this->_parseVars();
00112
00113 if ($qty = $this->getFieldValue($filters, 'qty')) {
00114 $qtyFrom = isset($qty['from']) ? $qty['from'] : 0;
00115 $qtyTo = isset($qty['to']) ? $qty['to'] : 0;
00116
00117 $qtyAttr = array();
00118 $qtyAttr['alias'] = 'qty';
00119 $qtyAttr['attribute'] = 'cataloginventory/stock_item';
00120 $qtyAttr['field'] = 'qty';
00121 $qtyAttr['bind'] = 'product_id=entity_id';
00122 $qtyAttr['cond'] = "{{table}}.qty between '{$qtyFrom}' AND '{$qtyTo}'";
00123 $qtyAttr['joinType'] = 'inner';
00124
00125 $this->setJoinField($qtyAttr);
00126 }
00127
00128 parent::setFilter($attrFilterArray, $attrToDb);
00129
00130 if ($price = $this->getFieldValue($filters, 'price')) {
00131 $this->_filter[] = array(
00132 'attribute' => 'price',
00133 'from' => $price['from'],
00134 'to' => $price['to']
00135 );
00136 $this->setJoinAttr(array(
00137 'alias' => 'price',
00138 'attribute' => 'catalog_product/price',
00139 'bind' => 'entity_id',
00140 'joinType' => 'LEFT'
00141 ));
00142 }
00143
00144 return parent::load();
00145 }
00146
00147
00148
00149
00150
00151
00152 public function getProductModel()
00153 {
00154 if (is_null($this->_productModel)) {
00155 $productModel = Mage::getModel('catalog/product');
00156 $this->_productModel = Mage::objects()->save($productModel);
00157 }
00158 return Mage::objects()->load($this->_productModel);
00159 }
00160
00161
00162
00163
00164
00165
00166
00167 public function getAttribute($code)
00168 {
00169 if (!isset($this->_attributes[$code])) {
00170 $this->_attributes[$code] = $this->getProductModel()->getResource()->getAttribute($code);
00171 }
00172 if ($this->_attributes[$code] instanceof Mage_Catalog_Model_Resource_Eav_Attribute) {
00173 $applyTo = $this->_attributes[$code]->getApplyTo();
00174 if ($applyTo && !in_array($this->getProductModel()->getTypeId(), $applyTo)) {
00175 return false;
00176 }
00177 }
00178 return $this->_attributes[$code];
00179 }
00180
00181
00182
00183
00184
00185
00186 public function getProductTypes()
00187 {
00188 if (is_null($this->_productTypes)) {
00189 $this->_productTypes = array();
00190 $options = Mage::getModel('catalog/product_type')
00191 ->getOptionArray();
00192 foreach ($options as $k => $v) {
00193 $this->_productTypes[$k] = $k;
00194 }
00195 }
00196 return $this->_productTypes;
00197 }
00198
00199
00200
00201
00202
00203
00204
00205 public function setProductTypeInstance(Mage_Catalog_Model_Product $product)
00206 {
00207 $type = $product->getTypeId();
00208 if (!isset($this->_productTypeInstances[$type])) {
00209 $this->_productTypeInstances[$type] = Mage::getSingleton('catalog/product_type')
00210 ->factory($product, true);
00211 }
00212 $product->setTypeInstance($this->_productTypeInstances[$type], true);
00213 return $this;
00214 }
00215
00216
00217
00218
00219
00220
00221 public function getProductAttributeSets()
00222 {
00223 if (is_null($this->_productAttributeSets)) {
00224 $this->_productAttributeSets = array();
00225
00226 $entityTypeId = Mage::getModel('eav/entity')
00227 ->setType('catalog_product')
00228 ->getTypeId();
00229 $collection = Mage::getResourceModel('eav/entity_attribute_set_collection')
00230 ->setEntityTypeFilter($entityTypeId);
00231 foreach ($collection as $set) {
00232 $this->_productAttributeSets[$set->getAttributeSetName()] = $set->getId();
00233 }
00234 }
00235 return $this->_productAttributeSets;
00236 }
00237
00238
00239
00240
00241 protected function _initStores ()
00242 {
00243 if (is_null($this->_stores)) {
00244 $this->_stores = Mage::app()->getStores(true, true);
00245 foreach ($this->_stores as $code => $store) {
00246 $this->_storesIdCode[$store->getId()] = $code;
00247 }
00248 }
00249 }
00250
00251
00252
00253
00254
00255
00256
00257 public function getStoreByCode($store)
00258 {
00259 $this->_initStores();
00260
00261
00262
00263 if (Mage::app()->isSingleStoreMode()) {
00264 return Mage::app()->getStore(Mage_Catalog_Model_Abstract::DEFAULT_STORE_ID);
00265 }
00266
00267 if (isset($this->_stores[$store])) {
00268 return $this->_stores[$store];
00269 }
00270 return false;
00271 }
00272
00273
00274
00275
00276
00277
00278
00279 public function getStoreById($id)
00280 {
00281 $this->_initStores();
00282
00283
00284
00285 if (Mage::app()->isSingleStoreMode()) {
00286 return Mage::app()->getStore(Mage_Catalog_Model_Abstract::DEFAULT_STORE_ID);
00287 }
00288
00289 if (isset($this->_storesIdCode[$id])) {
00290 return $this->getStoreByCode($this->_storesIdCode[$id]);
00291 }
00292 return false;
00293 }
00294
00295 public function parse()
00296 {
00297 $batchModel = Mage::getSingleton('dataflow/batch');
00298
00299
00300 $batchImportModel = $batchModel->getBatchImportModel();
00301 $importIds = $batchImportModel->getIdCollection();
00302
00303 foreach ($importIds as $importId) {
00304
00305 $batchImportModel->load($importId);
00306 $importData = $batchImportModel->getBatchData();
00307
00308 $this->saveRow($importData);
00309 }
00310 }
00311
00312 protected $_productId = '';
00313
00314
00315
00316
00317
00318 public function __construct()
00319 {
00320 $fieldset = Mage::getConfig()->getFieldset('catalog_product_dataflow', 'admin');
00321 foreach ($fieldset as $code => $node) {
00322
00323 if ($node->is('inventory')) {
00324 foreach ($node->product_type->children() as $productType) {
00325 $productType = $productType->getName();
00326 $this->_inventoryFieldsProductTypes[$productType][] = $code;
00327 if ($node->is('use_config')) {
00328 $this->_inventoryFieldsProductTypes[$productType][] = 'use_config_' . $code;
00329 }
00330 }
00331
00332 $this->_inventoryFields[] = $code;
00333 if ($node->is('use_config')) {
00334 $this->_inventoryFields[] = 'use_config_'.$code;
00335 }
00336 }
00337 if ($node->is('required')) {
00338 $this->_requiredFields[] = $code;
00339 }
00340 if ($node->is('ignore')) {
00341 $this->_ignoreFields[] = $code;
00342 }
00343 if ($node->is('img')) {
00344 $this->_imageFields[] = $code;
00345 }
00346 if ($node->is('to_number')) {
00347 $this->_toNumber[] = $code;
00348 }
00349 }
00350
00351 $this->setVar('entity_type', 'catalog/product');
00352 if (!Mage::registry('Object_Cache_Product')) {
00353 $this->setProduct(Mage::getModel('catalog/product'));
00354 }
00355
00356 if (!Mage::registry('Object_Cache_StockItem')) {
00357 $this->setStockItem(Mage::getModel('cataloginventory/stock_item'));
00358 }
00359 }
00360
00361
00362
00363
00364
00365
00366
00367 protected function _getCollectionForLoad($entityType)
00368 {
00369 $collection = parent::_getCollectionForLoad($entityType)
00370 ->setStoreId($this->getStoreId())
00371 ->addStoreFilter($this->getStoreId());
00372 return $collection;
00373 }
00374
00375 public function setProduct(Mage_Catalog_Model_Product $object)
00376 {
00377 $id = Mage::objects()->save($object);
00378
00379 Mage::register('Object_Cache_Product', $id);
00380 }
00381
00382 public function getProduct()
00383 {
00384 return Mage::objects()->load(Mage::registry('Object_Cache_Product'));
00385 }
00386
00387 public function setStockItem(Mage_CatalogInventory_Model_Stock_Item $object)
00388 {
00389 $id = Mage::objects()->save($object);
00390
00391 Mage::register('Object_Cache_StockItem', $id);
00392
00393
00394 }
00395
00396 public function getStockItem()
00397 {
00398 return Mage::objects()->load(Mage::registry('Object_Cache_StockItem'));
00399
00400 }
00401
00402 public function save()
00403 {
00404 $stores = array();
00405 foreach (Mage::getConfig()->getNode('stores')->children() as $storeNode) {
00406 $stores[(int)$storeNode->system->store->id] = $storeNode->getName();
00407 }
00408
00409 $collections = $this->getData();
00410 if ($collections instanceof Mage_Catalog_Model_Entity_Product_Collection) {
00411 $collections = array($collections->getEntity()->getStoreId()=>$collections);
00412 } elseif (!is_array($collections)) {
00413 $this->addException(Mage::helper('catalog')->__('No product collections found'), Mage_Dataflow_Model_Convert_Exception::FATAL);
00414 }
00415
00416
00417 $stockItems = Mage::registry('current_imported_inventory');
00418 if ($collections) foreach ($collections as $storeId=>$collection) {
00419 $this->addException(Mage::helper('catalog')->__('Records for "'.$stores[$storeId].'" store found'));
00420
00421 if (!$collection instanceof Mage_Catalog_Model_Entity_Product_Collection) {
00422 $this->addException(Mage::helper('catalog')->__('Product collection expected'), Mage_Dataflow_Model_Convert_Exception::FATAL);
00423 }
00424 try {
00425 $i = 0;
00426 foreach ($collection->getIterator() as $model) {
00427 $new = false;
00428
00429 if (!$model->getId()) {
00430 $new = true;
00431 $model->save();
00432
00433
00434
00435 if (0 !== $storeId ) {
00436 $data = $model->getData();
00437 $default = Mage::getModel('catalog/product');
00438 $default->setData($data);
00439 $default->setStoreId(0);
00440 $default->save();
00441 unset($default);
00442 }
00443
00444 #Mage::getResourceSingleton('catalog_entity/convert')->addProductToStore($model->getId(), 0);
00445 }
00446 if (!$new || 0!==$storeId) {
00447 if (0!==$storeId) {
00448 Mage::getResourceSingleton('catalog_entity/convert')->addProductToStore($model->getId(), $storeId);
00449 }
00450 $model->save();
00451 }
00452
00453 if (isset($stockItems[$model->getSku()]) && $stock = $stockItems[$model->getSku()]) {
00454 $stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($model->getId());
00455 $stockItemId = $stockItem->getId();
00456
00457 if (!$stockItemId) {
00458 $stockItem->setData('product_id', $model->getId());
00459 $stockItem->setData('stock_id', 1);
00460 $data = array();
00461 } else {
00462 $data = $stockItem->getData();
00463 }
00464
00465 foreach($stock as $field => $value) {
00466 if (!$stockItemId) {
00467 if (in_array($field, $this->_configs)) {
00468 $stockItem->setData('use_config_'.$field, 0);
00469 }
00470 $stockItem->setData($field, $value?$value:0);
00471 } else {
00472
00473 if (in_array($field, $this->_configs)) {
00474 if ($data['use_config_'.$field] == 0) {
00475 $stockItem->setData($field, $value?$value:0);
00476 }
00477 } else {
00478 $stockItem->setData($field, $value?$value:0);
00479 }
00480 }
00481 }
00482 $stockItem->save();
00483 unset($data);
00484 unset($stockItem);
00485 unset($stockItemId);
00486 }
00487 unset($model);
00488 $i++;
00489 }
00490 $this->addException(Mage::helper('catalog')->__("Saved ".$i." record(s)"));
00491 } catch (Exception $e) {
00492 if (!$e instanceof Mage_Dataflow_Model_Convert_Exception) {
00493 $this->addException(Mage::helper('catalog')->__('Problem saving the collection, aborting. Error: %s', $e->getMessage()),
00494 Mage_Dataflow_Model_Convert_Exception::FATAL);
00495 }
00496 }
00497 }
00498
00499 unset($collections);
00500 return $this;
00501 }
00502
00503
00504
00505
00506
00507
00508
00509
00510 public function saveRow(array $importData)
00511 {
00512 $product = $this->getProductModel()
00513 ->reset();
00514
00515 if (empty($importData['store'])) {
00516 if (!is_null($this->getBatchParams('store'))) {
00517 $store = $this->getStoreById($this->getBatchParams('store'));
00518 } else {
00519 $message = Mage::helper('catalog')->__('Skip import row, required field "%s" not defined', 'store');
00520 Mage::throwException($message);
00521 }
00522 }
00523 else {
00524 $store = $this->getStoreByCode($importData['store']);
00525 }
00526
00527 if ($store === false) {
00528 $message = Mage::helper('catalog')->__('Skip import row, store "%s" field not exists', $importData['store']);
00529 Mage::throwException($message);
00530 }
00531
00532 if (empty($importData['sku'])) {
00533 $message = Mage::helper('catalog')->__('Skip import row, required field "%s" not defined', 'sku');
00534 Mage::throwException($message);
00535 }
00536 $product->setStoreId($store->getId());
00537 $productId = $product->getIdBySku($importData['sku']);
00538
00539 if ($productId) {
00540 $product->load($productId);
00541 }
00542 else {
00543 $productTypes = $this->getProductTypes();
00544 $productAttributeSets = $this->getProductAttributeSets();
00545
00546
00547
00548
00549 if (empty($importData['type']) || !isset($productTypes[strtolower($importData['type'])])) {
00550 $value = isset($importData['type']) ? $importData['type'] : '';
00551 $message = Mage::helper('catalog')->__('Skip import row, is not valid value "%s" for field "%s"', $value, 'type');
00552 Mage::throwException($message);
00553 }
00554 $product->setTypeId($productTypes[strtolower($importData['type'])]);
00555
00556
00557
00558 if (empty($importData['attribute_set']) || !isset($productAttributeSets[$importData['attribute_set']])) {
00559 $value = isset($importData['attribute_set']) ? $importData['attribute_set'] : '';
00560 $message = Mage::helper('catalog')->__('Skip import row, is not valid value "%s" for field "%s"', $value, 'attribute_set');
00561 Mage::throwException($message);
00562 }
00563 $product->setAttributeSetId($productAttributeSets[$importData['attribute_set']]);
00564
00565 foreach ($this->_requiredFields as $field) {
00566 $attribute = $this->getAttribute($field);
00567 if (!isset($importData[$field]) && $attribute && $attribute->getIsRequired()) {
00568 $message = Mage::helper('catalog')->__('Skip import row, required field "%s" for new products not defined', $field);
00569 Mage::throwException($message);
00570 }
00571 }
00572 }
00573
00574 $this->setProductTypeInstance($product);
00575
00576 if (isset($importData['category_ids'])) {
00577 $product->setCategoryIds($importData['category_ids']);
00578 }
00579
00580 foreach ($this->_ignoreFields as $field) {
00581 if (isset($importData[$field])) {
00582 unset($importData[$field]);
00583 }
00584 }
00585
00586 if ($store->getId() != 0) {
00587 $websiteIds = $product->getWebsiteIds();
00588 if (!is_array($websiteIds)) {
00589 $websiteIds = array();
00590 }
00591 if (!in_array($store->getWebsiteId(), $websiteIds)) {
00592 $websiteIds[] = $store->getWebsiteId();
00593 }
00594 $product->setWebsiteIds($websiteIds);
00595 }
00596
00597 if (isset($importData['websites'])) {
00598 $websiteIds = $product->getWebsiteIds();
00599 if (!is_array($websiteIds)) {
00600 $websiteIds = array();
00601 }
00602 $websiteCodes = split(',', $importData['websites']);
00603 foreach ($websiteCodes as $websiteCode) {
00604 try {
00605 $website = Mage::app()->getWebsite(trim($websiteCode));
00606 if (!in_array($website->getId(), $websiteIds)) {
00607 $websiteIds[] = $website->getId();
00608 }
00609 }
00610 catch (Exception $e) {}
00611 }
00612 $product->setWebsiteIds($websiteIds);
00613 unset($websiteIds);
00614 }
00615
00616 foreach ($importData as $field => $value) {
00617 if (in_array($field, $this->_inventoryFields)) {
00618 continue;
00619 }
00620 if (in_array($field, $this->_imageFields)) {
00621 continue;
00622 }
00623
00624 $attribute = $this->getAttribute($field);
00625 if (!$attribute) {
00626 continue;
00627 }
00628
00629 $isArray = false;
00630 $setValue = $value;
00631
00632 if ($attribute->getFrontendInput() == 'multiselect') {
00633 $value = split(self::MULTI_DELIMITER, $value);
00634 $isArray = true;
00635 $setValue = array();
00636 }
00637
00638 if ($value && $attribute->getBackendType() == 'decimal') {
00639 $setValue = $this->getNumber($value);
00640 }
00641
00642 if ($attribute->usesSource()) {
00643 $options = $attribute->getSource()->getAllOptions(false);
00644
00645 if ($isArray) {
00646 foreach ($options as $item) {
00647 if (in_array($item['label'], $value)) {
00648 $setValue[] = $item['value'];
00649 }
00650 }
00651 }
00652 else {
00653 $setValue = null;
00654 foreach ($options as $item) {
00655 if ($item['label'] == $value) {
00656 $setValue = $item['value'];
00657 }
00658 }
00659 }
00660 }
00661
00662 $product->setData($field, $setValue);
00663 }
00664
00665 if (!$product->getVisibility()) {
00666 $product->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_NOT_VISIBLE);
00667 }
00668
00669 $stockData = array();
00670 $inventoryFields = isset($this->_inventoryFieldsProductTypes[$product->getTypeId()])
00671 ? $this->_inventoryFieldsProductTypes[$product->getTypeId()]
00672 : array();
00673 foreach ($inventoryFields as $field) {
00674 if (isset($importData[$field])) {
00675 if (in_array($field, $this->_toNumber)) {
00676 $stockData[$field] = $this->getNumber($importData[$field]);
00677 }
00678 else {
00679 $stockData[$field] = $importData[$field];
00680 }
00681 }
00682 }
00683 $product->setStockData($stockData);
00684
00685 $imageData = array();
00686 foreach ($this->_imageFields as $field) {
00687 if (!empty($importData[$field]) && $importData[$field] != 'no_selection') {
00688 if (!isset($imageData[$importData[$field]])) {
00689 $imageData[$importData[$field]] = array();
00690 }
00691 $imageData[$importData[$field]][] = $field;
00692 }
00693 }
00694
00695 foreach ($imageData as $file => $fields) {
00696 try {
00697 $product->addImageToMediaGallery(Mage::getBaseDir('media') . DS . 'import' . $file, $fields);
00698 }
00699 catch (Exception $e) {}
00700 }
00701
00702 $product->setIsMassupdate(true);
00703 $product->setExcludeUrlRewrite(true);
00704
00705 $product->save();
00706
00707 return true;
00708 }
00709
00710
00711
00712
00713
00714
00715
00716 public function saveRowSilently(array $importData)
00717 {
00718 try {
00719 $result = $this->saveRow($importData);
00720 return $result;
00721 }
00722 catch (Exception $e) {
00723 return false;
00724 }
00725 }
00726
00727
00728
00729
00730
00731 public function finish()
00732 {
00733 Mage::dispatchEvent('catalog_product_import_after', array());
00734 }
00735 }