PageRenderTime 62ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/app/code/core/Mage/Catalog/Model/Convert/Parser/Product.php

https://bitbucket.org/claudiu_marginean/magento-hg-mirror
PHP | 527 lines | 348 code | 59 blank | 120 comment | 55 complexity | 2a7a6bc6b80cc3166dbc300cc696f42f 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. class Mage_Catalog_Model_Convert_Parser_Product
  27. extends Mage_Eav_Model_Convert_Parser_Abstract
  28. {
  29. const MULTI_DELIMITER = ' , ';
  30. protected $_resource;
  31. /**
  32. * Product collections per store
  33. *
  34. * @var array
  35. */
  36. protected $_collections;
  37. /**
  38. * Product Type Instances object cache
  39. *
  40. * @var array
  41. */
  42. protected $_productTypeInstances = array();
  43. /**
  44. * Product Type cache
  45. *
  46. * @var array
  47. */
  48. protected $_productTypes;
  49. protected $_inventoryFields = array();
  50. protected $_imageFields = array();
  51. protected $_systemFields = array();
  52. protected $_internalFields = array();
  53. protected $_externalFields = array();
  54. protected $_inventoryItems = array();
  55. protected $_productModel;
  56. protected $_setInstances = array();
  57. protected $_store;
  58. protected $_storeId;
  59. protected $_attributes = array();
  60. public function __construct()
  61. {
  62. foreach (Mage::getConfig()->getFieldset('catalog_product_dataflow', 'admin') as $code=>$node) {
  63. if ($node->is('inventory')) {
  64. $this->_inventoryFields[] = $code;
  65. if ($node->is('use_config')) {
  66. $this->_inventoryFields[] = 'use_config_'.$code;
  67. }
  68. }
  69. if ($node->is('internal')) {
  70. $this->_internalFields[] = $code;
  71. }
  72. if ($node->is('system')) {
  73. $this->_systemFields[] = $code;
  74. }
  75. if ($node->is('external')) {
  76. $this->_externalFields[$code] = $code;
  77. }
  78. if ($node->is('img')) {
  79. $this->_imageFields[] = $code;
  80. }
  81. }
  82. }
  83. /**
  84. * @return Mage_Catalog_Model_Mysql4_Convert
  85. */
  86. public function getResource()
  87. {
  88. if (!$this->_resource) {
  89. $this->_resource = Mage::getResourceSingleton('catalog_entity/convert');
  90. #->loadStores()
  91. #->loadProducts()
  92. #->loadAttributeSets()
  93. #->loadAttributeOptions();
  94. }
  95. return $this->_resource;
  96. }
  97. public function getCollection($storeId)
  98. {
  99. if (!isset($this->_collections[$storeId])) {
  100. $this->_collections[$storeId] = Mage::getResourceModel('catalog/product_collection');
  101. $this->_collections[$storeId]->getEntity()->setStore($storeId);
  102. }
  103. return $this->_collections[$storeId];
  104. }
  105. /**
  106. * Retrieve product type options
  107. *
  108. * @return array
  109. */
  110. public function getProductTypes()
  111. {
  112. if (is_null($this->_productTypes)) {
  113. $this->_productTypes = Mage::getSingleton('catalog/product_type')
  114. ->getOptionArray();
  115. }
  116. return $this->_productTypes;
  117. }
  118. /**
  119. * Retrieve Product type name by code
  120. *
  121. * @param string $code
  122. * @return string
  123. */
  124. public function getProductTypeName($code)
  125. {
  126. $productTypes = $this->getProductTypes();
  127. if (isset($productTypes[$code])) {
  128. return $productTypes[$code];
  129. }
  130. return false;
  131. }
  132. /**
  133. * Retrieve product type code by name
  134. *
  135. * @param string $name
  136. * @return string
  137. */
  138. public function getProductTypeId($name)
  139. {
  140. $productTypes = $this->getProductTypes();
  141. if ($code = array_search($name, $productTypes)) {
  142. return $code;
  143. }
  144. return false;
  145. }
  146. /**
  147. * Retrieve product model cache
  148. *
  149. * @return Mage_Catalog_Model_Product
  150. */
  151. public function getProductModel()
  152. {
  153. if (is_null($this->_productModel)) {
  154. $productModel = Mage::getModel('catalog/product');
  155. $this->_productModel = Mage::objects()->save($productModel);
  156. }
  157. return Mage::objects()->load($this->_productModel);
  158. }
  159. /**
  160. * Retrieve current store model
  161. *
  162. * @return Mage_Core_Model_Store
  163. */
  164. public function getStore()
  165. {
  166. if (is_null($this->_store)) {
  167. try {
  168. $store = Mage::app()->getStore($this->getVar('store'));
  169. } catch (Exception $e) {
  170. $this->addException(
  171. Mage::helper('catalog')->__('Invalid store specified'),
  172. Varien_Convert_Exception::FATAL
  173. );
  174. throw $e;
  175. }
  176. $this->_store = $store;
  177. }
  178. return $this->_store;
  179. }
  180. /**
  181. * Retrieve store ID
  182. *
  183. * @return int
  184. */
  185. public function getStoreId()
  186. {
  187. if (is_null($this->_storeId)) {
  188. $this->_storeId = $this->getStore()->getId();
  189. }
  190. return $this->_storeId;
  191. }
  192. /**
  193. * ReDefine Product Type Instance to Product
  194. *
  195. * @param Mage_Catalog_Model_Product $product
  196. * @return Mage_Catalog_Model_Convert_Parser_Product
  197. */
  198. public function setProductTypeInstance(Mage_Catalog_Model_Product $product)
  199. {
  200. $type = $product->getTypeId();
  201. if (!isset($this->_productTypeInstances[$type])) {
  202. $this->_productTypeInstances[$type] = Mage::getSingleton('catalog/product_type')
  203. ->factory($product, true);
  204. }
  205. $product->setTypeInstance($this->_productTypeInstances[$type], true);
  206. return $this;
  207. }
  208. public function getAttributeSetInstance()
  209. {
  210. $productType = $this->getProductModel()->getType();
  211. $attributeSetId = $this->getProductModel()->getAttributeSetId();
  212. if (!isset($this->_setInstances[$productType][$attributeSetId])) {
  213. $this->_setInstances[$productType][$attributeSetId] =
  214. Mage::getSingleton('catalog/product_type')->factory($this->getProductModel());
  215. }
  216. return $this->_setInstances[$productType][$attributeSetId];
  217. }
  218. /**
  219. * Retrieve eav entity attribute model
  220. *
  221. * @param string $code
  222. * @return Mage_Eav_Model_Entity_Attribute
  223. */
  224. public function getAttribute($code)
  225. {
  226. if (!isset($this->_attributes[$code])) {
  227. $this->_attributes[$code] = $this->getProductModel()->getResource()->getAttribute($code);
  228. }
  229. return $this->_attributes[$code];
  230. }
  231. /**
  232. * @deprecated not used anymore
  233. */
  234. public function parse()
  235. {
  236. $data = $this->getData();
  237. $entityTypeId = Mage::getSingleton('eav/config')->getEntityType('catalog_product')->getId();
  238. $inventoryFields = array();
  239. foreach ($data as $i=>$row) {
  240. $this->setPosition('Line: '.($i+1));
  241. try {
  242. // validate SKU
  243. if (empty($row['sku'])) {
  244. $this->addException(
  245. Mage::helper('catalog')->__('Missing SKU, skipping the record.'),
  246. Mage_Dataflow_Model_Convert_Exception::ERROR
  247. );
  248. continue;
  249. }
  250. $this->setPosition('Line: '.($i+1).', SKU: '.$row['sku']);
  251. // try to get entity_id by sku if not set
  252. if (empty($row['entity_id'])) {
  253. $row['entity_id'] = $this->getResource()->getProductIdBySku($row['sku']);
  254. }
  255. // if attribute_set not set use default
  256. if (empty($row['attribute_set'])) {
  257. $row['attribute_set'] = 'Default';
  258. }
  259. // get attribute_set_id, if not throw error
  260. $row['attribute_set_id'] = $this->getAttributeSetId($entityTypeId, $row['attribute_set']);
  261. if (!$row['attribute_set_id']) {
  262. $this->addException(
  263. Mage::helper('catalog')->__('Invalid attribute set specified, skipping the record.'),
  264. Mage_Dataflow_Model_Convert_Exception::ERROR
  265. );
  266. continue;
  267. }
  268. if (empty($row['type'])) {
  269. $row['type'] = 'Simple';
  270. }
  271. // get product type_id, if not throw error
  272. $row['type_id'] = $this->getProductTypeId($row['type']);
  273. if (!$row['type_id']) {
  274. $this->addException(
  275. Mage::helper('catalog')->__('Invalid product type specified, skipping the record.'),
  276. Mage_Dataflow_Model_Convert_Exception::ERROR
  277. );
  278. continue;
  279. }
  280. // get store ids
  281. $storeIds = $this->getStoreIds(isset($row['store']) ? $row['store'] : $this->getVar('store'));
  282. if (!$storeIds) {
  283. $this->addException(
  284. Mage::helper('catalog')->__('Invalid store specified, skipping the record.'),
  285. Mage_Dataflow_Model_Convert_Exception::ERROR
  286. );
  287. continue;
  288. }
  289. // import data
  290. $rowError = false;
  291. foreach ($storeIds as $storeId) {
  292. $collection = $this->getCollection($storeId);
  293. $entity = $collection->getEntity();
  294. $model = Mage::getModel('catalog/product');
  295. $model->setStoreId($storeId);
  296. if (!empty($row['entity_id'])) {
  297. $model->load($row['entity_id']);
  298. }
  299. foreach ($row as $field=>$value) {
  300. $attribute = $entity->getAttribute($field);
  301. if (!$attribute) {
  302. //$inventoryFields[$row['sku']][$field] = $value;
  303. if (in_array($field, $this->_inventoryFields)) {
  304. $inventoryFields[$row['sku']][$field] = $value;
  305. }
  306. continue;
  307. // $this->addException(
  308. // Mage::helper('catalog')->__('Unknown attribute: %s.', $field),
  309. // Mage_Dataflow_Model_Convert_Exception::ERROR
  310. // );
  311. }
  312. if ($attribute->usesSource()) {
  313. $source = $attribute->getSource();
  314. $optionId = $this->getSourceOptionId($source, $value);
  315. if (is_null($optionId)) {
  316. $rowError = true;
  317. $this->addException(
  318. Mage::helper('catalog')->__('Invalid attribute option specified for attribute %s (%s), skipping the record.', $field, $value),
  319. Mage_Dataflow_Model_Convert_Exception::ERROR
  320. );
  321. continue;
  322. }
  323. $value = $optionId;
  324. }
  325. $model->setData($field, $value);
  326. }//foreach ($row as $field=>$value)
  327. //echo 'Before **********************<br/><pre>';
  328. //print_r($model->getData());
  329. if (!$rowError) {
  330. $collection->addItem($model);
  331. }
  332. unset($model);
  333. } //foreach ($storeIds as $storeId)
  334. } catch (Exception $e) {
  335. if (!$e instanceof Mage_Dataflow_Model_Convert_Exception) {
  336. $this->addException(
  337. Mage::helper('catalog')->__('Error during retrieval of option value: %s', $e->getMessage()),
  338. Mage_Dataflow_Model_Convert_Exception::FATAL
  339. );
  340. }
  341. }
  342. }
  343. // set importinted to adaptor
  344. if (sizeof($inventoryFields) > 0) {
  345. Mage::register('current_imported_inventory', $inventoryFields);
  346. //$this->setInventoryItems($inventoryFields);
  347. } // end setting imported to adaptor
  348. $this->setData($this->_collections);
  349. return $this;
  350. }
  351. public function setInventoryItems($items)
  352. {
  353. $this->_inventoryItems = $items;
  354. }
  355. public function getInventoryItems()
  356. {
  357. return $this->_inventoryItems;
  358. }
  359. /**
  360. * Unparse (prepare data) loaded products
  361. *
  362. * @return Mage_Catalog_Model_Convert_Parser_Product
  363. */
  364. public function unparse()
  365. {
  366. $entityIds = $this->getData();
  367. foreach ($entityIds as $i => $entityId) {
  368. $product = $this->getProductModel()
  369. ->setStoreId($this->getStoreId())
  370. ->load($entityId);
  371. $this->setProductTypeInstance($product);
  372. /* @var $product Mage_Catalog_Model_Product */
  373. $position = Mage::helper('catalog')->__('Line %d, SKU: %s', ($i+1), $product->getSku());
  374. $this->setPosition($position);
  375. $row = array(
  376. 'store' => $this->getStore()->getCode(),
  377. 'websites' => '',
  378. 'attribute_set' => $this->getAttributeSetName($product->getEntityTypeId(),
  379. $product->getAttributeSetId()),
  380. 'type' => $product->getTypeId(),
  381. 'category_ids' => join(',', $product->getCategoryIds())
  382. );
  383. if ($this->getStore()->getCode() == Mage_Core_Model_Store::ADMIN_CODE) {
  384. $websiteCodes = array();
  385. foreach ($product->getWebsiteIds() as $websiteId) {
  386. $websiteCode = Mage::app()->getWebsite($websiteId)->getCode();
  387. $websiteCodes[$websiteCode] = $websiteCode;
  388. }
  389. $row['websites'] = join(',', $websiteCodes);
  390. } else {
  391. $row['websites'] = $this->getStore()->getWebsite()->getCode();
  392. if ($this->getVar('url_field')) {
  393. $row['url'] = $product->getProductUrl(false);
  394. }
  395. }
  396. foreach ($product->getData() as $field => $value) {
  397. if (in_array($field, $this->_systemFields) || is_object($value)) {
  398. continue;
  399. }
  400. $attribute = $this->getAttribute($field);
  401. if (!$attribute) {
  402. continue;
  403. }
  404. if ($attribute->usesSource()) {
  405. $option = $attribute->getSource()->getOptionText($value);
  406. if ($value && empty($option) && $option != '0') {
  407. $this->addException(
  408. Mage::helper('catalog')->__('Invalid option ID specified for %s (%s), skipping the record.', $field, $value),
  409. Mage_Dataflow_Model_Convert_Exception::ERROR
  410. );
  411. continue;
  412. }
  413. if (is_array($option)) {
  414. $value = join(self::MULTI_DELIMITER, $option);
  415. } else {
  416. $value = $option;
  417. }
  418. unset($option);
  419. } elseif (is_array($value)) {
  420. continue;
  421. }
  422. $row[$field] = $value;
  423. }
  424. if ($stockItem = $product->getStockItem()) {
  425. foreach ($stockItem->getData() as $field => $value) {
  426. if (in_array($field, $this->_systemFields) || is_object($value)) {
  427. continue;
  428. }
  429. $row[$field] = $value;
  430. }
  431. }
  432. foreach ($this->_imageFields as $field) {
  433. if (isset($row[$field]) && $row[$field] == 'no_selection') {
  434. $row[$field] = null;
  435. }
  436. }
  437. $batchExport = $this->getBatchExportModel()
  438. ->setId(null)
  439. ->setBatchId($this->getBatchModel()->getId())
  440. ->setBatchData($row)
  441. ->setStatus(1)
  442. ->save();
  443. $product->reset();
  444. }
  445. return $this;
  446. }
  447. /**
  448. * Retrieve accessible external product attributes
  449. *
  450. * @return array
  451. */
  452. public function getExternalAttributes()
  453. {
  454. $productAttributes = Mage::getResourceModel('catalog/product_attribute_collection')->load();
  455. $attributes = $this->_externalFields;
  456. foreach ($productAttributes as $attr) {
  457. $code = $attr->getAttributeCode();
  458. if (in_array($code, $this->_internalFields) || $attr->getFrontendInput() == 'hidden') {
  459. continue;
  460. }
  461. $attributes[$code] = $code;
  462. }
  463. foreach ($this->_inventoryFields as $field) {
  464. $attributes[$field] = $field;
  465. }
  466. return $attributes;
  467. }
  468. }