PageRenderTime 675ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/app/code/core/Mage/Dataflow/Model/Profile.php

https://bitbucket.org/claudiu_marginean/magento-hg-mirror
PHP | 395 lines | 290 code | 38 blank | 67 comment | 63 complexity | 920929539424f8178e7a52b862026aa4 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_Dataflow
  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. * Convert profile
  28. *
  29. * @author Magento Core Team <core@magentocommerce.com>
  30. */
  31. class Mage_Dataflow_Model_Profile extends Mage_Core_Model_Abstract
  32. {
  33. const DEFAULT_EXPORT_PATH = 'var/export';
  34. const DEFAULT_EXPORT_FILENAME = 'export_';
  35. protected function _construct()
  36. {
  37. $this->_init('dataflow/profile');
  38. }
  39. protected function _afterLoad()
  40. {
  41. if (is_string($this->getGuiData())) {
  42. $guiData = unserialize($this->getGuiData());
  43. } else {
  44. $guiData = '';
  45. }
  46. $this->setGuiData($guiData);
  47. parent::_afterLoad();
  48. }
  49. protected function _beforeSave()
  50. {
  51. parent::_beforeSave();
  52. $actionsXML = $this->getData('actions_xml');
  53. if (strlen($actionsXML) < 0 &&
  54. @simplexml_load_string('<data>' . $actionsXML . '</data>', null, LIBXML_NOERROR) === false) {
  55. Mage::throwException(Mage::helper("dataflow")->__("Actions XML is not valid."));
  56. }
  57. if (is_array($this->getGuiData())) {
  58. $data = $this->getData();
  59. $guiData = $this->getGuiData();
  60. $charSingleList = array('\\', '/', '.', '!', '@', '#', '$', '%', '&', '*', '~', '^');
  61. if (isset($guiData['file']['type']) && $guiData['file']['type'] == 'file') {
  62. if (empty($guiData['file']['path'])
  63. || (strlen($guiData['file']['path']) == 1
  64. && in_array($guiData['file']['path'], $charSingleList))) {
  65. $guiData['file']['path'] = self::DEFAULT_EXPORT_PATH;
  66. }
  67. if (empty($guiData['file']['filename'])) {
  68. $guiData['file']['filename'] = self::DEFAULT_EXPORT_FILENAME . $data['entity_type']
  69. . '.' . ($guiData['parse']['type']=='csv' ? $guiData['parse']['type'] : 'xml');
  70. }
  71. //validate export available path
  72. $path = rtrim($guiData['file']['path'], '\\/')
  73. . DS . $guiData['file']['filename'];
  74. /** @var $validator Mage_Core_Model_File_Validator_AvailablePath */
  75. $validator = Mage::getModel('core/file_validator_availablePath');
  76. /** @var $helperImportExport Mage_ImportExport_Helper_Data */
  77. $helperImportExport = Mage::helper('importexport');
  78. $validator->setPaths($helperImportExport->getLocalValidPaths());
  79. if (!$validator->isValid($path)) {
  80. foreach ($validator->getMessages() as $message) {
  81. Mage::throwException($message);
  82. }
  83. }
  84. $this->setGuiData($guiData);
  85. }
  86. $this->_parseGuiData();
  87. $this->setGuiData(serialize($this->getGuiData()));
  88. }
  89. if ($this->_getResource()->isProfileExists($this->getName(), $this->getId())) {
  90. Mage::throwException(Mage::helper("dataflow")->__("Profile with the same name already exists."));
  91. }
  92. }
  93. protected function _afterSave()
  94. {
  95. if (is_string($this->getGuiData())) {
  96. $this->setGuiData(unserialize($this->getGuiData()));
  97. }
  98. Mage::getModel('dataflow/profile_history')
  99. ->setProfileId($this->getId())
  100. ->setActionCode($this->getOrigData('profile_id') ? 'update' : 'create')
  101. ->save();
  102. if (isset($_FILES['file_1']['tmp_name']) || isset($_FILES['file_2']['tmp_name'])
  103. || isset($_FILES['file_3']['tmp_name'])) {
  104. for ($index = 0; $index < 3; $index++) {
  105. if ($file = $_FILES['file_' . ($index+1)]['tmp_name']) {
  106. $uploader = new Mage_Core_Model_File_Uploader('file_' . ($index + 1));
  107. $uploader->setAllowedExtensions(array('csv','xml'));
  108. $path = Mage::app()->getConfig()->getTempVarDir() . '/import/';
  109. $uploader->save($path);
  110. if ($uploadFile = $uploader->getUploadedFileName()) {
  111. $newFilename = 'import-' . date('YmdHis') . '-' . ($index+1) . '_' . $uploadFile;
  112. rename($path . $uploadFile, $path . $newFilename);
  113. }
  114. }
  115. //BOM deleting for UTF files
  116. if (isset($newFilename) && $newFilename) {
  117. $contents = file_get_contents($path . $newFilename);
  118. if (ord($contents[0]) == 0xEF && ord($contents[1]) == 0xBB && ord($contents[2]) == 0xBF) {
  119. $contents = substr($contents, 3);
  120. file_put_contents($path . $newFilename, $contents);
  121. }
  122. unset($contents);
  123. }
  124. }
  125. }
  126. parent::_afterSave();
  127. }
  128. /**
  129. * Run profile
  130. *
  131. * @return Mage_Dataflow_Model_Profile
  132. */
  133. public function run()
  134. {
  135. /**
  136. * Save history
  137. */
  138. Mage::getModel('dataflow/profile_history')
  139. ->setProfileId($this->getId())
  140. ->setActionCode('run')
  141. ->save();
  142. /**
  143. * Prepare xml convert profile actions data
  144. */
  145. $xml = '<convert version="1.0"><profile name="default">' . $this->getActionsXml()
  146. . '</profile></convert>';
  147. $profile = Mage::getModel('core/convert')
  148. ->importXml($xml)
  149. ->getProfile('default');
  150. /* @var $profile Mage_Dataflow_Model_Convert_Profile */
  151. try {
  152. $batch = Mage::getSingleton('dataflow/batch')
  153. ->setProfileId($this->getId())
  154. ->setStoreId($this->getStoreId())
  155. ->save();
  156. $this->setBatchId($batch->getId());
  157. $profile->setDataflowProfile($this->getData());
  158. $profile->run();
  159. }
  160. catch (Exception $e) {
  161. echo $e;
  162. }
  163. // if ($batch) {
  164. // $batch->delete();
  165. // }
  166. $this->setExceptions($profile->getExceptions());
  167. return $this;
  168. }
  169. public function _parseGuiData()
  170. {
  171. $nl = "\r\n";
  172. $import = $this->getDirection()==='import';
  173. $p = $this->getGuiData();
  174. if ($this->getDataTransfer()==='interactive') {
  175. // $p['file']['type'] = 'file';
  176. // $p['file']['filename'] = $p['interactive']['filename'];
  177. // $p['file']['path'] = 'var/export';
  178. $interactiveXml = '<action type="dataflow/convert_adapter_http" method="'
  179. . ($import ? 'load' : 'save') . '">' . $nl;
  180. #$interactiveXml .= ' <var name="filename"><![CDATA['.$p['interactive']['filename'].']]></var>'.$nl;
  181. $interactiveXml .= '</action>';
  182. $fileXml = '';
  183. } else {
  184. $interactiveXml = '';
  185. $fileXml = '<action type="dataflow/convert_adapter_io" method="'
  186. . ($import ? 'load' : 'save') . '">' . $nl;
  187. $fileXml .= ' <var name="type">' . $p['file']['type'] . '</var>' . $nl;
  188. $fileXml .= ' <var name="path">' . $p['file']['path'] . '</var>' . $nl;
  189. $fileXml .= ' <var name="filename"><![CDATA[' . $p['file']['filename'] . ']]></var>' . $nl;
  190. if ($p['file']['type']==='ftp') {
  191. $hostArr = explode(':', $p['file']['host']);
  192. $fileXml .= ' <var name="host"><![CDATA[' . $hostArr[0] . ']]></var>' . $nl;
  193. if (isset($hostArr[1])) {
  194. $fileXml .= ' <var name="port"><![CDATA[' . $hostArr[1] . ']]></var>' . $nl;
  195. }
  196. if (!empty($p['file']['passive'])) {
  197. $fileXml .= ' <var name="passive">true</var>' . $nl;
  198. }
  199. if ((!empty($p['file']['file_mode']))
  200. && ($p['file']['file_mode'] == FTP_ASCII || $p['file']['file_mode'] == FTP_BINARY)
  201. ) {
  202. $fileXml .= ' <var name="file_mode">' . $p['file']['file_mode'] . '</var>' . $nl;
  203. }
  204. if (!empty($p['file']['user'])) {
  205. $fileXml .= ' <var name="user"><![CDATA[' . $p['file']['user'] . ']]></var>' . $nl;
  206. }
  207. if (!empty($p['file']['password'])) {
  208. $fileXml .= ' <var name="password"><![CDATA[' . $p['file']['password'] . ']]></var>' . $nl;
  209. }
  210. }
  211. if ($import) {
  212. $fileXml .= ' <var name="format"><![CDATA[' . $p['parse']['type'] . ']]></var>' . $nl;
  213. }
  214. $fileXml .= '</action>' . $nl . $nl;
  215. }
  216. switch ($p['parse']['type']) {
  217. case 'excel_xml':
  218. $parseFileXml = '<action type="dataflow/convert_parser_xml_excel" method="'
  219. . ($import ? 'parse' : 'unparse') . '">' . $nl;
  220. $parseFileXml .= ' <var name="single_sheet"><![CDATA['
  221. . ($p['parse']['single_sheet'] !== '' ? $p['parse']['single_sheet'] : '')
  222. . ']]></var>' . $nl;
  223. break;
  224. case 'csv':
  225. $parseFileXml = '<action type="dataflow/convert_parser_csv" method="'
  226. . ($import ? 'parse' : 'unparse') . '">' . $nl;
  227. $parseFileXml .= ' <var name="delimiter"><![CDATA['
  228. . $p['parse']['delimiter'] . ']]></var>' . $nl;
  229. $parseFileXml .= ' <var name="enclose"><![CDATA['
  230. . $p['parse']['enclose'] . ']]></var>' . $nl;
  231. break;
  232. }
  233. $parseFileXml .= ' <var name="fieldnames">' . $p['parse']['fieldnames'] . '</var>' . $nl;
  234. $parseFileXmlInter = $parseFileXml;
  235. $parseFileXml .= '</action>' . $nl . $nl;
  236. $mapXml = '';
  237. if (isset($p['map']) && is_array($p['map'])) {
  238. foreach ($p['map'] as $side=>$fields) {
  239. if (!is_array($fields)) {
  240. continue;
  241. }
  242. foreach ($fields['db'] as $i=>$k) {
  243. if ($k=='' || $k=='0') {
  244. unset($p['map'][$side]['db'][$i]);
  245. unset($p['map'][$side]['file'][$i]);
  246. }
  247. }
  248. }
  249. }
  250. $mapXml .= '<action type="dataflow/convert_mapper_column" method="map">' . $nl;
  251. $map = $p['map'][$this->getEntityType()];
  252. if (sizeof($map['db']) > 0) {
  253. $from = $map[$import?'file':'db'];
  254. $to = $map[$import?'db':'file'];
  255. $mapXml .= ' <var name="map">' . $nl;
  256. $parseFileXmlInter .= ' <var name="map">' . $nl;
  257. foreach ($from as $i=>$f) {
  258. $mapXml .= ' <map name="' . $f . '"><![CDATA[' . $to[$i] . ']]></map>' . $nl;
  259. $parseFileXmlInter .= ' <map name="' . $f . '"><![CDATA[' . $to[$i] . ']]></map>' . $nl;
  260. }
  261. $mapXml .= ' </var>' . $nl;
  262. $parseFileXmlInter .= ' </var>' . $nl;
  263. }
  264. if ($p['map']['only_specified']) {
  265. $mapXml .= ' <var name="_only_specified">' . $p['map']['only_specified'] . '</var>' . $nl;
  266. //$mapXml .= ' <var name="map">' . $nl;
  267. $parseFileXmlInter .= ' <var name="_only_specified">' . $p['map']['only_specified'] . '</var>' . $nl;
  268. }
  269. $mapXml .= '</action>' . $nl . $nl;
  270. $parsers = array(
  271. 'product'=>'catalog/convert_parser_product',
  272. 'customer'=>'customer/convert_parser_customer',
  273. );
  274. if ($import) {
  275. // if ($this->getDataTransfer()==='interactive') {
  276. $parseFileXmlInter .= ' <var name="store"><![CDATA[' . $this->getStoreId() . ']]></var>' . $nl;
  277. // } else {
  278. // $parseDataXml = '<action type="' . $parsers[$this->getEntityType()] . '" method="parse">' . $nl;
  279. // $parseDataXml = ' <var name="store"><![CDATA[' . $this->getStoreId() . ']]></var>' . $nl;
  280. // $parseDataXml .= '</action>'.$nl.$nl;
  281. // }
  282. // $parseDataXml = '<action type="'.$parsers[$this->getEntityType()].'" method="parse">'.$nl;
  283. // $parseDataXml .= ' <var name="store"><![CDATA['.$this->getStoreId().']]></var>'.$nl;
  284. // $parseDataXml .= '</action>'.$nl.$nl;
  285. } else {
  286. $parseDataXml = '<action type="' . $parsers[$this->getEntityType()] . '" method="unparse">' . $nl;
  287. $parseDataXml .= ' <var name="store"><![CDATA[' . $this->getStoreId() . ']]></var>' . $nl;
  288. if (isset($p['export']['add_url_field'])) {
  289. $parseDataXml .= ' <var name="url_field"><![CDATA['
  290. . $p['export']['add_url_field'] . ']]></var>' . $nl;
  291. }
  292. $parseDataXml .= '</action>' . $nl . $nl;
  293. }
  294. $adapters = array(
  295. 'product'=>'catalog/convert_adapter_product',
  296. 'customer'=>'customer/convert_adapter_customer',
  297. );
  298. if ($import) {
  299. $entityXml = '<action type="' . $adapters[$this->getEntityType()] . '" method="save">' . $nl;
  300. $entityXml .= ' <var name="store"><![CDATA[' . $this->getStoreId() . ']]></var>' . $nl;
  301. $entityXml .= '</action>' . $nl . $nl;
  302. } else {
  303. $entityXml = '<action type="' . $adapters[$this->getEntityType()] . '" method="load">' . $nl;
  304. $entityXml .= ' <var name="store"><![CDATA[' . $this->getStoreId() . ']]></var>' . $nl;
  305. foreach ($p[$this->getEntityType()]['filter'] as $f=>$v) {
  306. if (empty($v)) {
  307. continue;
  308. }
  309. if (is_scalar($v)) {
  310. $entityXml .= ' <var name="filter/' . $f . '"><![CDATA[' . $v . ']]></var>' . $nl;
  311. $parseFileXmlInter .= ' <var name="filter/' . $f . '"><![CDATA[' . $v . ']]></var>' . $nl;
  312. } elseif (is_array($v)) {
  313. foreach ($v as $a=>$b) {
  314. if (strlen($b) == 0) {
  315. continue;
  316. }
  317. $entityXml .= ' <var name="filter/' . $f . '/' . $a
  318. . '"><![CDATA[' . $b . ']]></var>' . $nl;
  319. $parseFileXmlInter .= ' <var name="filter/' . $f . '/'
  320. . $a . '"><![CDATA[' . $b . ']]></var>' . $nl;
  321. }
  322. }
  323. }
  324. $entityXml .= '</action>' . $nl . $nl;
  325. }
  326. // Need to rewrite the whole xml action format
  327. if ($import) {
  328. $numberOfRecords = isset($p['import']['number_of_records']) ? $p['import']['number_of_records'] : 1;
  329. $decimalSeparator = isset($p['import']['decimal_separator']) ? $p['import']['decimal_separator'] : ' . ';
  330. $parseFileXmlInter .= ' <var name="number_of_records">'
  331. . $numberOfRecords . '</var>' . $nl;
  332. $parseFileXmlInter .= ' <var name="decimal_separator"><![CDATA['
  333. . $decimalSeparator . ']]></var>' . $nl;
  334. if ($this->getDataTransfer()==='interactive') {
  335. $xml = $parseFileXmlInter;
  336. $xml .= ' <var name="adapter">' . $adapters[$this->getEntityType()] . '</var>' . $nl;
  337. $xml .= ' <var name="method">parse</var>' . $nl;
  338. $xml .= '</action>';
  339. } else {
  340. $xml = $fileXml;
  341. $xml .= $parseFileXmlInter;
  342. $xml .= ' <var name="adapter">' . $adapters[$this->getEntityType()] . '</var>' . $nl;
  343. $xml .= ' <var name="method">parse</var>' . $nl;
  344. $xml .= '</action>';
  345. }
  346. //$xml = $interactiveXml.$fileXml.$parseFileXml.$mapXml.$parseDataXml.$entityXml;
  347. } else {
  348. $xml = $entityXml . $parseDataXml . $mapXml . $parseFileXml . $fileXml . $interactiveXml;
  349. }
  350. $this->setGuiData($p);
  351. $this->setActionsXml($xml);
  352. /*echo "<pre>" . print_r($p,1) . "</pre>";
  353. echo "<xmp>" . $xml . "</xmp>";
  354. die;*/
  355. return $this;
  356. }
  357. }