*/ class Mage_Dataflow_Model_Convert_Parser_Xml_Excel extends Mage_Dataflow_Model_Convert_Parser_Abstract { /** * Simple Xml object * * @var SimpleXMLElement */ protected $_xmlElement; /** * Field list * * @var array */ protected $_parseFieldNames; public function parse() { $adapterName = $this->getVar('adapter', null); $adapterMethod = $this->getVar('method', 'saveRow'); if (!$adapterName || !$adapterMethod) { $message = Mage::helper('dataflow')->__('Please declare "adapter" and "method" nodes first.'); $this->addException($message, Mage_Dataflow_Model_Convert_Exception::FATAL); return $this; } try { $adapter = Mage::getModel($adapterName); } catch (Exception $e) { $message = Mage::helper('dataflow')->__('Declared adapter %s was not found.', $adapterName); $this->addException($message, Mage_Dataflow_Model_Convert_Exception::FATAL); return $this; } if (!method_exists($adapter, $adapterMethod)) { $message = Mage::helper('dataflow')->__('Method "%s" was not defined in adapter %s.', $adapterMethod, $adapterName); $this->addException($message, Mage_Dataflow_Model_Convert_Exception::FATAL); return $this; } $batchModel = $this->getBatchModel(); $batchIoAdapter = $this->getBatchModel()->getIoAdapter(); if (Mage::app()->getRequest()->getParam('files')) { $file = Mage::app()->getConfig()->getTempVarDir().'/import/' . urldecode(Mage::app()->getRequest()->getParam('files')); $this->_copy($file); } $batchIoAdapter->open(false); $isFieldNames = $this->getVar('fieldnames', '') == 'true' ? true : false; if (!$isFieldNames && is_array($this->getVar('map'))) { $this->_parseFieldNames = $this->getVar('map'); } $worksheet = $this->getVar('single_sheet', ''); $xmlString = $xmlRowString = ''; $countRows = 0; $isWorksheet = $isRow = false; while (($xmlOriginalString = $batchIoAdapter->read()) !== false) { $xmlString .= $xmlOriginalString; if (!$isWorksheet) { $strposS = strpos($xmlString, ''); if ($strposF === false) { $xmlString = $xmlTmpString; continue; } if (!$worksheet) { $xmlString = substr($xmlTmpString, $strposF); $isWorksheet = true; continue; } else { if (preg_match('/ss:Name=\"'.preg_quote($worksheet).'\"/siU', substr($xmlTmpString, 0, $strposF))) { $xmlString = substr($xmlTmpString, $strposF); $isWorksheet = true; continue; } else { $xmlString = ''; continue; } } } else { $xmlString = $this->_parseXmlRow($xmlString); $strposS = strpos($xmlString, ''); $substrL = 12; //fix for OpenOffice if ($strposS === false) { $strposS = strpos($xmlString, ''); $substrL = 15; } if ($strposS !== false) { $xmlString = substr($xmlString, $strposS + $substrL); $isWorksheet = false; continue; } } } $this->addException(Mage::helper('dataflow')->__('Found %d rows.', $this->_countRows)); $this->addException(Mage::helper('dataflow')->__('Starting %s :: %s', $adapterName, $adapterMethod)); $batchModel->setParams($this->getVars()) ->setAdapter($adapterName) ->save(); // $adapter->$adapterMethod(); return $this; $dom = new DOMDocument(); // $dom->loadXML($this->getData()); if (Mage::app()->getRequest()->getParam('files')) { $path = Mage::app()->getConfig()->getTempVarDir().'/import/'; $file = $path.urldecode(Mage::app()->getRequest()->getParam('files')); if (file_exists($file)) { $dom->load($file); } } else { $this->validateDataString(); $dom->loadXML($this->getData()); } $worksheets = $dom->getElementsByTagName('Worksheet'); if ($this->getVar('adapter') && $this->getVar('method')) { $adapter = Mage::getModel($this->getVar('adapter')); } foreach ($worksheets as $worksheet) { $wsName = $worksheet->getAttribute('ss:Name'); $rows = $worksheet->getElementsByTagName('Row'); $firstRow = true; $fieldNames = array(); $wsData = array(); $i = 0; foreach ($rows as $rowSet) { $index = 1; $cells = $rowSet->getElementsByTagName('Cell'); $rowData = array(); foreach ($cells as $cell) { $value = $cell->getElementsByTagName('Data')->item(0)->nodeValue; $ind = $cell->getAttribute('ss:Index'); if (!is_null($ind) && $ind>0) { $index = $ind; } if ($firstRow && !$this->getVar('fieldnames')) { $fieldNames[$index] = 'column'.$index; } if ($firstRow && $this->getVar('fieldnames')) { $fieldNames[$index] = $value; } else { $rowData[$fieldNames[$index]] = $value; } $index++; } $row = $rowData; if ($row) { $loadMethod = $this->getVar('method'); $adapter->$loadMethod(compact('i', 'row')); } $i++; $firstRow = false; if (!empty($rowData)) { $wsData[] = $rowData; } } $data[$wsName] = $wsData; $this->addException('Found worksheet "'.$wsName.'" with '.sizeof($wsData).' row(s)'); } if ($wsName = $this->getVar('single_sheet')) { if (isset($data[$wsName])) { $data = $data[$wsName]; } else { reset($data); $data = current($data); } } $this->setData($data); return $this; } /** * Parse MS Excel XML string * * @param string $xmlString * @return string */ protected function _parseXmlRow($xmlString) { $found = true; while ($found === true) { $strposS = strpos($xmlString, ''); if ($strposF !== false) { $xmlRowString = substr($xmlTmpString, 0, $strposF + 6); $this->_saveParsedRow($xmlRowString); $xmlString = substr($xmlTmpString, $strposF + 6); } else { $found = false; continue; } } return $xmlString; } protected function _saveParsedRow($xmlString) { $xml = '<'.'?xml version="1.0"?'.'><'.'?mso-application progid="Excel.Sheet"?' .'>' . $xmlString .''; try { $xmlElement = new SimpleXMLElement($xml); } catch (Exception $e) { $message = 'Invalid XML row'; $this->addException($message, Mage_Dataflow_Model_Convert_Exception::ERROR); return $this; } $xmlData = array(); $itemData = array(); $cellIndex = 0; foreach ($xmlElement->Row->children() as $cell) { if (is_null($this->_parseFieldNames)) { $xmlData[(string)$cell->Data] = (string)$cell->Data; } else { $attributes = $cell->attributes('urn:schemas-microsoft-com:office:spreadsheet'); if ($attributes && isset($attributes['Index'])) { $cellIndex = $attributes['Index'] - 1; } $xmlData[$cellIndex] = (string)$cell->Data; $cellIndex ++; } } if (is_null($this->_parseFieldNames)) { $this->_parseFieldNames = $xmlData; return $this; } $this->_countRows ++; $i = 0; foreach ($this->_parseFieldNames as $field) { $itemData[$field] = isset($xmlData[$i]) ? $xmlData[$i] : null; $i ++; } $batchImportModel = $this->getBatchImportModel() ->setId(null) ->setBatchId($this->getBatchModel()->getId()) ->setBatchData($itemData) ->setStatus(1) ->save(); return $this; } public function unparse() { $batchExport = $this->getBatchExportModel() ->setBatchId($this->getBatchModel()->getId()); $fieldList = $this->getBatchModel()->getFieldList(); $batchExportIds = $batchExport->getIdCollection(); if (!is_array($batchExportIds)) { return $this; } $io = $this->getBatchModel()->getIoAdapter(); $io->open(); $xml = '<'.'?xml version="1.0"?'.'><'.'?mso-application progid="Excel.Sheet"?' .'>' .'' .'' .'' .''; $io->write($xml); $wsName = htmlspecialchars($this->getVar('single_sheet')); $wsName = !empty($wsName) ? $wsName : Mage::helper('dataflow')->__('Sheet 1'); $xml = ''; $io->write($xml); if ($this->getVar('fieldnames')) { $xml = $this->_getXmlString($fieldList); $io->write($xml); } foreach ($batchExportIds as $batchExportId) { $xmlData = array(); $batchExport->load($batchExportId); $row = $batchExport->getBatchData(); foreach ($fieldList as $field) { $xmlData[] = isset($row[$field]) ? $row[$field] : ''; } $xmlData = $this->_getXmlString($xmlData); $io->write($xmlData); } $xml = '
'; $io->write($xml); $io->close(); return $this; // if ($wsName = $this->getVar('single_sheet')) { // $data = array($wsName => $this->getData()); // } else { // $data = $this->getData(); // } // // $this->validateDataGrid(); // // $xml = '<'.'?xml version="1.0"?'.'><'.'?mso-application progid="Excel.Sheet"?'.'>' // .'' // .'' // .'' // .''; // // if (is_array($data)) { // foreach ($data as $wsName=>$wsData) { // if (!is_array($wsData)) { // continue; // } // $fields = $this->getGridFields($wsData); // // $xml .= ''; // if ($this->getVar('fieldnames')) { // $xml .= ''; // foreach ($fields as $fieldName) { // $xml .= ''.$fieldName.''; // } // $xml .= ''; // } // foreach ($wsData as $i=>$row) { // if (!is_array($row)) { // continue; // } // $xml .= ''; // foreach ($fields as $fieldName) { // $data = isset($row[$fieldName]) ? $row[$fieldName] : ''; // $xml .= ''.$data.''; // } // $xml .= ''; // } // $xml .= '
'; // } // } // // $xml .= ''; // // $this->setData($xml); // // return $this; } /** * Prepare and return XML string for MS Excel XML from array * * @param array $fields * @return string */ protected function _getXmlString(array $fields = array()) { $xmlHeader = '' . "\n"; $xmlRegexp = '/^(.*)?<\/row><\/cell>\s?$/ms'; if (is_null($this->_xmlElement)) { $xmlString = $xmlHeader . ''; $this->_xmlElement = new SimpleXMLElement($xmlString, LIBXML_NOBLANKS); } $xmlData = array(); $xmlData[] = ''; foreach ($fields as $value) { $this->_xmlElement->row = htmlspecialchars($value); $value = str_replace($xmlHeader, '', $this->_xmlElement->asXML()); $value = preg_replace($xmlRegexp, '\\1', $value); if (is_numeric($value)) { $value = trim($value); $dataType = 'Number'; } else { $dataType = 'String'; } $value = str_replace(array("\r\n", "\r", "\n"), ' ', $value); $xmlData[] = '' . $value . ''; } $xmlData[] = ''; return join('', $xmlData); } }