2 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
4 /*********************************************************************************
5 * SugarCRM Community Edition is a customer relationship management program developed by
6 * SugarCRM, Inc. Copyright (C) 2004-2012 SugarCRM Inc.
8 * This program is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU Affero General Public License version 3 as published by the
10 * Free Software Foundation with the addition of the following permission added
11 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
12 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
13 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
15 * This program is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
20 * You should have received a copy of the GNU Affero General Public License along with
21 * this program; if not, see http://www.gnu.org/licenses or write to the Free
22 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
26 * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
28 * The interactive user interfaces in modified source and object code versions
29 * of this program must display Appropriate Legal Notices, as required under
30 * Section 5 of the GNU Affero General Public License version 3.
32 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
33 * these Appropriate Legal Notices must retain the display of the "Powered by
34 * SugarCRM" logo. If the display of the logo is not reasonably feasible for
35 * technical reasons, the Appropriate Legal Notices must display the words
36 * "Powered by SugarCRM".
37 ********************************************************************************/
40 require_once('modules/Import/ImportCacheFiles.php');
44 abstract class ImportDataSource implements Iterator
47 * The current offset the data set should start at
49 protected $_offset = 0;
52 * Count of rows processed
54 protected $_rowsCount = 0;
57 * True if the current row has already had an error it in, so we don't increase the $_errorCount
59 protected $_rowCountedForErrors = false;
62 * Count of rows with errors
64 private $_errorCount = 0;
67 * Count of duplicate rows
69 private $_dupeCount = 0;
72 * Count of newly created rows
74 private $_createdCount = 0;
77 * Count of updated rows
79 private $_updatedCount = 0;
82 * Sourcename used as an identifier for this import
84 protected $_sourcename;
87 * Array of the values in the current array we are in
89 protected $_currentRow = FALSE;
92 * Holds any locale settings needed for import. These can be provided by the user
93 * or explicitly set by the user.
95 protected $_localeSettings = array();
98 * Stores a subset or entire portion of the data set requested.
100 protected $_dataSet = array();
103 * Return a result set from the external source as an associative array with the key value equal to the
104 * external field name and the rvalue equal to the actual value.
107 * @param int $startIndex
108 * @param int $maxResults
111 abstract public function loadDataSet($maxResults = 0);
114 * Return the total count of records that will be imported.
119 abstract public function getTotalRecordCount();
125 abstract public function getHeaderColumns();
128 * Set the source name.
133 public function setSourceName($sourceName = '')
135 $this->_sourcename = $sourceName;
140 * Set the current offset.
145 public function setCurrentOffset($offset)
147 $this->_offset = $offset;
151 * Return the current offset
155 public function getCurrentOffset()
157 return $this->_offset;
161 * Return the current data set loaded.
165 public function getDataSet()
167 return $this->_dataSet;
171 * Add this row to the UsersLastImport table
173 * @param string $import_module name of the module we are doing the import into
174 * @param string $module name of the bean we are creating for this import
175 * @param string $id id of the recorded created in the $module
177 public static function writeRowToLastImport($import_module, $module, $id)
179 // cache $last_import instance
182 if ( !($last_import instanceof UsersLastImport) )
183 $last_import = new UsersLastImport();
185 $last_import->id = null;
186 $last_import->deleted = null;
187 $last_import->assigned_user_id = $GLOBALS['current_user']->id;
188 $last_import->import_module = $import_module;
189 if ( $module == 'Case' )
192 $last_import->bean_type = $module;
193 $last_import->bean_id = $id;
194 return $last_import->save();
199 * Writes the row out to the ImportCacheFiles::getErrorFileName() file
201 * @param $error string
202 * @param $fieldName string
203 * @param $fieldValue mixed
205 public function writeError($error, $fieldName, $fieldValue)
207 $fp = sugar_fopen(ImportCacheFiles::getErrorFileName(),'a');
208 fputcsv($fp,array($error,$fieldName,$fieldValue,$this->_rowsCount));
211 if ( !$this->_rowCountedForErrors )
213 $this->_errorCount++;
214 $this->_rowCountedForErrors = true;
215 $this->writeErrorRecord($this->formatErrorMessage($error, $fieldName, $fieldValue));
219 protected function formatErrorMessage($error, $fieldName, $fieldValue)
221 global $current_language;
222 $mod_strings = return_module_language($current_language, 'Import');
223 return "<b>{$mod_strings['LBL_ERROR']}</b> $error <br/>".
224 "<b>{$mod_strings['LBL_FIELD_NAME']}</b> $fieldName <br/>" .
225 "<b>{$mod_strings['LBL_VALUE']}</b> $fieldValue <br/>";
227 public function resetRowErrorCounter()
229 $this->_rowCountedForErrors = false;
233 * Writes the totals and filename out to the ImportCacheFiles::getStatusFileName() file
235 public function writeStatus()
237 $fp = sugar_fopen(ImportCacheFiles::getStatusFileName(),'a');
238 $statusData = array($this->_rowsCount,$this->_errorCount,$this->_dupeCount,
239 $this->_createdCount,$this->_updatedCount,$this->_sourcename);
240 fputcsv($fp, $statusData);
245 * Writes the row out to the ImportCacheFiles::getDuplicateFileName() file
247 public function markRowAsDuplicate($field_names=array())
249 $fp = sugar_fopen(ImportCacheFiles::getDuplicateFileName(),'a');
250 fputcsv($fp, $this->_currentRow);
253 //if available, grab the column number based on passed in field_name
254 if(!empty($field_names))
259 //REQUEST should have the field names in order as they appear in the row to be written, get the key values
260 //of passed in fields into an array
261 foreach($field_names as $fv)
264 if(empty($fv) || $fv == 'delete')
266 $new_keys = array_keys($_REQUEST, $fv);
267 $colnums = array_merge($colnums,$new_keys);
271 //if values were found, process for number position
274 //foreach column, strip the 'colnum_' prefix to the get the column key value
275 foreach($colnums as $column_key)
277 if(strpos($column_key,'colnum_') === 0)
279 $colkey = substr($column_key,7);
282 //if we have the column key, then lets add a span tag with styling reference to the original value
285 $hilited_val = $this->_currentRow[$colkey];
286 $this->_currentRow[$colkey]= '<span class=warn>'.$hilited_val.'</span>';
292 //add the row (with or without stylings) to the list view, this will get displayed to the user as a list of duplicates
293 $fdp = sugar_fopen(ImportCacheFiles::getDuplicateFileDisplayName(),'a');
294 fputcsv($fdp, $this->_currentRow);
297 //increment dupecount
302 * Marks whether this row created a new record or not
304 * @param $createdRecord bool true if record is created, false if it is just updated
306 public function markRowAsImported($createdRecord = true)
308 if ( $createdRecord )
309 ++$this->_createdCount;
311 ++$this->_updatedCount;
315 * Writes the row out to the ImportCacheFiles::getErrorRecordsFileName() file
317 public function writeErrorRecord($errorMessage = '')
319 $rowData = !$this->_currentRow ? array() : $this->_currentRow;
320 $fp = sugar_fopen(ImportCacheFiles::getErrorRecordsFileName(),'a');
321 $fpNoErrors = sugar_fopen(ImportCacheFiles::getErrorRecordsWithoutErrorFileName(),'a');
323 //Write records only for download without error message.
324 fputcsv($fpNoErrors, $rowData);
326 //Add the error message to the first column
327 array_unshift($rowData, $errorMessage);
328 fputcsv($fp, $rowData);
334 public function __get($var)
336 if( isset($_REQUEST[$var]) )
337 return $_REQUEST[$var];
338 else if( isset($this->_localeSettings[$var]) )
339 return $this->_localeSettings[$var];