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_Parser_Product
00029 extends Mage_Eav_Model_Convert_Parser_Abstract
00030 {
00031 const MULTI_DELIMITER = ' , ';
00032 protected $_resource;
00033
00034
00035
00036
00037
00038
00039 protected $_collections;
00040
00041
00042
00043
00044
00045
00046 protected $_productTypeInstances = array();
00047
00048
00049
00050
00051
00052
00053 protected $_productTypes;
00054
00055 protected $_inventoryFields = array();
00056
00057 protected $_imageFields = array();
00058
00059 protected $_systemFields = array();
00060 protected $_internalFields = array();
00061 protected $_externalFields = array();
00062
00063 protected $_inventoryItems = array();
00064
00065 protected $_productModel;
00066
00067 protected $_setInstances = array();
00068
00069 protected $_store;
00070 protected $_storeId;
00071 protected $_attributes = array();
00072
00073 public function __construct()
00074 {
00075 foreach (Mage::getConfig()->getFieldset('catalog_product_dataflow', 'admin') as $code=>$node) {
00076 if ($node->is('inventory')) {
00077 $this->_inventoryFields[] = $code;
00078 if ($node->is('use_config')) {
00079 $this->_inventoryFields[] = 'use_config_'.$code;
00080 }
00081 }
00082 if ($node->is('internal')) {
00083 $this->_internalFields[] = $code;
00084 }
00085 if ($node->is('system')) {
00086 $this->_systemFields[] = $code;
00087 }
00088 if ($node->is('external')) {
00089 $this->_externalFields[$code] = $code;
00090 }
00091 if ($node->is('img')) {
00092 $this->_imageFields[] = $code;
00093 }
00094 }
00095 }
00096
00097
00098
00099
00100 public function getResource()
00101 {
00102 if (!$this->_resource) {
00103 $this->_resource = Mage::getResourceSingleton('catalog_entity/convert');
00104 #->loadStores()
00105 #->loadProducts()
00106 #->loadAttributeSets()
00107 #->loadAttributeOptions();
00108 }
00109 return $this->_resource;
00110 }
00111
00112 public function getCollection($storeId)
00113 {
00114 if (!isset($this->_collections[$storeId])) {
00115 $this->_collections[$storeId] = Mage::getResourceModel('catalog/product_collection');
00116 $this->_collections[$storeId]->getEntity()->setStore($storeId);
00117 }
00118 return $this->_collections[$storeId];
00119 }
00120
00121
00122
00123
00124
00125
00126 public function getProductTypes()
00127 {
00128 if (is_null($this->_productTypes)) {
00129 $this->_productTypes = Mage::getSingleton('catalog/product_type')
00130 ->getOptionArray();
00131 }
00132 return $this->_productTypes;
00133 }
00134
00135
00136
00137
00138
00139
00140
00141 public function getProductTypeName($code)
00142 {
00143 $productTypes = $this->getProductTypes();
00144 if (isset($productTypes[$code])) {
00145 return $productTypes[$code];
00146 }
00147 return false;
00148 }
00149
00150
00151
00152
00153
00154
00155
00156 public function getProductTypeId($name)
00157 {
00158 $productTypes = $this->getProductTypes();
00159 if ($code = array_search($name, $productTypes)) {
00160 return $code;
00161 }
00162 return false;
00163 }
00164
00165
00166
00167
00168
00169
00170 public function getProductModel()
00171 {
00172 if (is_null($this->_productModel)) {
00173 $productModel = Mage::getModel('catalog/product');
00174 $this->_productModel = Mage::objects()->save($productModel);
00175 }
00176 return Mage::objects()->load($this->_productModel);
00177 }
00178
00179
00180
00181
00182
00183
00184 public function getStore()
00185 {
00186 if (is_null($this->_store)) {
00187 try {
00188 $store = Mage::app()->getStore($this->getVar('store'));
00189 }
00190 catch (Exception $e) {
00191 $this->addException(Mage::helper('catalog')->__('Invalid store specified'), Varien_Convert_Exception::FATAL);
00192 throw $e;
00193 }
00194 $this->_store = $store;
00195 }
00196 return $this->_store;
00197 }
00198
00199
00200
00201
00202
00203
00204 public function getStoreId()
00205 {
00206 if (is_null($this->_storeId)) {
00207 $this->_storeId = $this->getStore()->getId();
00208 }
00209 return $this->_storeId;
00210 }
00211
00212
00213
00214
00215
00216
00217
00218 public function setProductTypeInstance(Mage_Catalog_Model_Product $product)
00219 {
00220 $type = $product->getTypeId();
00221 if (!isset($this->_productTypeInstances[$type])) {
00222 $this->_productTypeInstances[$type] = Mage::getSingleton('catalog/product_type')
00223 ->factory($product, true);
00224 }
00225 $product->setTypeInstance($this->_productTypeInstances[$type], true);
00226 return $this;
00227 }
00228
00229 public function getAttributeSetInstance()
00230 {
00231 $productType = $this->getProductModel()->getType();
00232 $attributeSetId = $this->getProductModel()->getAttributeSetId();
00233
00234 if (!isset($this->_setInstances[$productType][$attributeSetId])) {
00235 $this->_setInstances[$productType][$attributeSetId] =
00236 Mage::getSingleton('catalog/product_type')->factory($this->getProductModel());
00237 }
00238
00239 return $this->_setInstances[$productType][$attributeSetId];
00240 }
00241
00242
00243
00244
00245
00246
00247
00248 public function getAttribute($code)
00249 {
00250 if (!isset($this->_attributes[$code])) {
00251 $this->_attributes[$code] = $this->getProductModel()->getResource()->getAttribute($code);
00252 }
00253 return $this->_attributes[$code];
00254 }
00255
00256
00257
00258
00259 public function parse()
00260 {
00261 $data = $this->getData();
00262
00263 $entityTypeId = Mage::getSingleton('eav/config')->getEntityType('catalog_product')->getId();
00264
00265 $result = array();
00266 $inventoryFields = array();
00267 foreach ($data as $i=>$row) {
00268 $this->setPosition('Line: '.($i+1));
00269 try {
00270
00271 if (empty($row['sku'])) {
00272 $this->addException(Mage::helper('catalog')->__('Missing SKU, skipping the record'), Mage_Dataflow_Model_Convert_Exception::ERROR);
00273 continue;
00274 }
00275 $this->setPosition('Line: '.($i+1).', SKU: '.$row['sku']);
00276
00277
00278 if (empty($row['entity_id'])) {
00279 $row['entity_id'] = $this->getResource()->getProductIdBySku($row['sku']);
00280 }
00281
00282
00283 if (empty($row['attribute_set'])) {
00284 $row['attribute_set'] = 'Default';
00285 }
00286
00287 $row['attribute_set_id'] = $this->getAttributeSetId($entityTypeId, $row['attribute_set']);
00288 if (!$row['attribute_set_id']) {
00289 $this->addException(Mage::helper('catalog')->__("Invalid attribute set specified, skipping the record"), Mage_Dataflow_Model_Convert_Exception::ERROR);
00290 continue;
00291 }
00292
00293 if (empty($row['type'])) {
00294 $row['type'] = 'Simple';
00295 }
00296
00297 $row['type_id'] = $this->getProductTypeId($row['type']);
00298 if (!$row['type_id']) {
00299 $this->addException(Mage::helper('catalog')->__("Invalid product type specified, skipping the record"), Mage_Dataflow_Model_Convert_Exception::ERROR);
00300 continue;
00301 }
00302
00303
00304 $storeIds = $this->getStoreIds(isset($row['store']) ? $row['store'] : $this->getVar('store'));
00305 if (!$storeIds) {
00306 $this->addException(Mage::helper('catalog')->__("Invalid store specified, skipping the record"), Mage_Dataflow_Model_Convert_Exception::ERROR);
00307 continue;
00308 }
00309
00310
00311 $rowError = false;
00312 foreach ($storeIds as $storeId) {
00313 $collection = $this->getCollection($storeId);
00314 $entity = $collection->getEntity();
00315
00316 $model = Mage::getModel('catalog/product');
00317 $model->setStoreId($storeId);
00318 if (!empty($row['entity_id'])) {
00319 $model->load($row['entity_id']);
00320 }
00321 foreach ($row as $field=>$value) {
00322 $attribute = $entity->getAttribute($field);
00323
00324 if (!$attribute) {
00325
00326
00327 if (in_array($field, $this->_inventoryFields)) {
00328 $inventoryFields[$row['sku']][$field] = $value;
00329 }
00330 continue;
00331 #$this->addException(Mage::helper('catalog')->__("Unknown attribute: %s", $field), Mage_Dataflow_Model_Convert_Exception::ERROR);
00332 }
00333 if ($attribute->usesSource()) {
00334 $source = $attribute->getSource();
00335 $optionId = $this->getSourceOptionId($source, $value);
00336 if (is_null($optionId)) {
00337 $rowError = true;
00338 $this->addException(Mage::helper('catalog')->__("Invalid attribute option specified for attribute %s (%s), skipping the record", $field, $value), Mage_Dataflow_Model_Convert_Exception::ERROR);
00339 continue;
00340 }
00341 $value = $optionId;
00342 }
00343 $model->setData($field, $value);
00344
00345 }
00346
00347
00348
00349 if (!$rowError) {
00350 $collection->addItem($model);
00351 }
00352 unset($model);
00353 }
00354 } catch (Exception $e) {
00355 if (!$e instanceof Mage_Dataflow_Model_Convert_Exception) {
00356 $this->addException(Mage::helper('catalog')->__("Error during retrieval of option value: %s", $e->getMessage()), Mage_Dataflow_Model_Convert_Exception::FATAL);
00357 }
00358 }
00359 }
00360
00361
00362 if (sizeof($inventoryFields) > 0) {
00363 Mage::register('current_imported_inventory', $inventoryFields);
00364
00365 }
00366
00367 $this->setData($this->_collections);
00368 return $this;
00369 }
00370
00371 public function setInventoryItems($items)
00372 {
00373 $this->_inventoryItems = $items;
00374 }
00375
00376 public function getInventoryItems()
00377 {
00378 return $this->_inventoryItems;
00379 }
00380
00381
00382
00383
00384
00385
00386 public function unparse()
00387 {
00388 $entityIds = $this->getData();
00389
00390 foreach ($entityIds as $i => $entityId) {
00391 $product = $this->getProductModel()
00392 ->reset()
00393 ->setStoreId($this->getStoreId())
00394 ->load($entityId);
00395 $this->setProductTypeInstance($product);
00396
00397
00398 $position = Mage::helper('catalog')->__('Line %d, SKU: %s', ($i+1), $product->getSku());
00399 $this->setPosition($position);
00400
00401 $row = array(
00402 'store' => $this->getStore()->getCode(),
00403 'websites' => '',
00404 'attribute_set' => $this->getAttributeSetName($product->getEntityTypeId(), $product->getAttributeSetId()),
00405 'type' => $product->getTypeId(),
00406 );
00407
00408 if ($this->getStore()->getCode() == Mage_Core_Model_Store::ADMIN_CODE) {
00409 $websiteCodes = array();
00410 foreach ($product->getWebsiteIds() as $websiteId) {
00411 $websiteCode = Mage::app()->getWebsite($websiteId)->getCode();
00412 $websiteCodes[$websiteCode] = $websiteCode;
00413 }
00414 $row['websites'] = join(',', $websiteCodes);
00415 }
00416 else {
00417 $row['websites'] = $this->getStore()->getWebsite()->getCode();
00418 if ($this->getVar('url_field')) {
00419 $row['url'] = $product->getProductUrl(false);
00420 }
00421 }
00422
00423 foreach ($product->getData() as $field => $value) {
00424 if (in_array($field, $this->_systemFields) || is_object($value)) {
00425 continue;
00426 }
00427
00428 $attribute = $this->getAttribute($field);
00429 if (!$attribute) {
00430 continue;
00431 }
00432
00433 if ($attribute->usesSource()) {
00434 $option = $attribute->getSource()->getOptionText($value);
00435 if ($value && empty($option)) {
00436 $message = Mage::helper('catalog')->__("Invalid option id specified for %s (%s), skipping the record", $field, $value);
00437 $this->addException($message, Mage_Dataflow_Model_Convert_Exception::ERROR);
00438 continue;
00439 }
00440 if (is_array($option)) {
00441 $value = join(self::MULTI_DELIMITER, $option);
00442 } else {
00443 $value = $option;
00444 }
00445 unset($option);
00446 }
00447 elseif (is_array($value)) {
00448 continue;
00449 }
00450
00451 $row[$field] = $value;
00452 }
00453
00454 if ($stockItem = $product->getStockItem()) {
00455 foreach ($stockItem->getData() as $field => $value) {
00456 if (in_array($field, $this->_systemFields) || is_object($value)) {
00457 continue;
00458 }
00459 $row[$field] = $value;
00460 }
00461 }
00462
00463 foreach ($this->_imageFields as $field) {
00464 if (isset($row[$field]) && $row[$field] == 'no_selection') {
00465 $row[$field] = null;
00466 }
00467 }
00468
00469 $batchExport = $this->getBatchExportModel()
00470 ->setId(null)
00471 ->setBatchId($this->getBatchModel()->getId())
00472 ->setBatchData($row)
00473 ->setStatus(1)
00474 ->save();
00475 }
00476
00477 return $this;
00478 }
00479
00480
00481
00482
00483
00484
00485 public function getExternalAttributes()
00486 {
00487 $entityTypeId = Mage::getSingleton('eav/config')->getEntityType('catalog_product')->getId();
00488 $productAttributes = Mage::getResourceModel('eav/entity_attribute_collection')
00489 ->setEntityTypeFilter($entityTypeId)
00490 ->load();
00491
00492 var_dump($this->_externalFields);
00493
00494 $attributes = $this->_externalFields;
00495
00496 foreach ($productAttributes as $attr) {
00497 $code = $attr->getAttributeCode();
00498 if (in_array($code, $this->_internalFields) || $attr->getFrontendInput() == 'hidden') {
00499 continue;
00500 }
00501 $attributes[$code] = $code;
00502 }
00503
00504 foreach ($this->_inventoryFields as $field) {
00505 $attributes[$field] = $field;
00506 }
00507
00508 return $attributes;
00509 }
00510 }