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