]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - modules/Import/sources/ImportDataSource.php
Release 6.5.0
[Github/sugarcrm.git] / modules / Import / sources / ImportDataSource.php
1 <?php
2 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3
4 /*********************************************************************************
5  * SugarCRM Community Edition is a customer relationship management program developed by
6  * SugarCRM, Inc. Copyright (C) 2004-2012 SugarCRM Inc.
7  * 
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.
14  * 
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
18  * details.
19  * 
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
23  * 02110-1301 USA.
24  * 
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.
27  * 
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.
31  * 
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  ********************************************************************************/
38
39
40 require_once('modules/Import/ImportCacheFiles.php');
41
42
43
44 abstract class ImportDataSource implements Iterator
45 {
46     /**
47      * The current offset the data set should start at
48      */
49     protected $_offset = 0;
50
51     /**
52      * Count of rows processed
53      */
54     protected $_rowsCount = 0;
55
56     /**
57      * True if the current row has already had an error it in, so we don't increase the $_errorCount
58      */
59     protected $_rowCountedForErrors = false;
60
61     /**
62      * Count of rows with errors
63      */
64     private $_errorCount = 0;
65
66     /**
67      * Count of duplicate rows
68      */
69     private $_dupeCount = 0;
70
71     /**
72      * Count of newly created rows
73      */
74     private $_createdCount = 0;
75
76     /**
77      * Count of updated rows
78      */
79     private $_updatedCount = 0;
80
81     /**
82      * Sourcename used as an identifier for this import
83      */
84     protected $_sourcename;
85
86     /**
87      * Array of the values in the current array we are in
88      */
89     protected $_currentRow = FALSE;
90
91     /**
92      * Holds any locale settings needed for import.  These can be provided by the user
93      * or explicitly set by the user.
94      */
95     protected $_localeSettings = array();
96
97     /**
98      * Stores a subset or entire portion of the data set requested.
99      */
100     protected $_dataSet = array();
101
102     /**
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.  
105      *
106      * @abstract
107      * @param  int $startIndex
108      * @param  int $maxResults
109      * @return void
110      */
111     abstract public function loadDataSet($maxResults = 0);
112
113     /**
114      * Return the total count of records that will be imported.
115      *
116      * @abstract
117      * @return int
118      */
119     abstract public function getTotalRecordCount();
120
121     /**
122      * @abstract
123      * @return void
124      */
125     abstract public function getHeaderColumns();
126     
127     /**
128      * Set the source name.
129      *
130      * @param  $sourceName
131      * @return void
132      */
133     public function setSourceName($sourceName = '')
134     {
135         $this->_sourcename = $sourceName;
136     }
137
138
139     /**
140      * Set the current offset.
141      *
142      * @param $offset
143      * @return void
144      */
145     public function setCurrentOffset($offset)
146     {
147         $this->_offset = $offset;
148     }
149
150     /**
151      * Return the current offset
152      *
153      * @return int
154      */
155     public function getCurrentOffset()
156     {
157         return $this->_offset;
158     }
159
160     /**
161      * Return the current data set loaded.
162      *
163      * @return array
164      */
165     public function getDataSet()
166     {
167         return $this->_dataSet;
168     }
169
170     /**
171      * Add this row to the UsersLastImport table
172      *
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
176      */
177     public static function writeRowToLastImport($import_module, $module, $id)
178     {
179         // cache $last_import instance
180         static $last_import;
181
182         if ( !($last_import instanceof UsersLastImport) )
183             $last_import = new UsersLastImport();
184
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' )
190             $module = 'aCase';
191         
192         $last_import->bean_type = $module;
193         $last_import->bean_id = $id;
194         return $last_import->save();
195     }
196
197
198     /**
199      * Writes the row out to the ImportCacheFiles::getErrorFileName() file
200      *
201      * @param $error string
202      * @param $fieldName string
203      * @param $fieldValue mixed
204      */
205     public function writeError($error, $fieldName, $fieldValue)
206     {
207         $fp = sugar_fopen(ImportCacheFiles::getErrorFileName(),'a');
208         fputcsv($fp,array($error,$fieldName,$fieldValue,$this->_rowsCount));
209         fclose($fp);
210
211         if ( !$this->_rowCountedForErrors )
212         {
213             $this->_errorCount++;
214             $this->_rowCountedForErrors = true;
215             $this->writeErrorRecord($this->formatErrorMessage($error, $fieldName, $fieldValue));
216         }
217     }
218
219     protected function formatErrorMessage($error, $fieldName, $fieldValue)
220     {
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/>";
226     }
227     public function resetRowErrorCounter()
228     {
229         $this->_rowCountedForErrors = false;
230     }
231
232     /**
233      * Writes the totals and filename out to the ImportCacheFiles::getStatusFileName() file
234      */
235     public function writeStatus()
236     {
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);
241         fclose($fp);
242     }
243
244     /**
245      * Writes the row out to the ImportCacheFiles::getDuplicateFileName() file
246      */
247     public function markRowAsDuplicate($field_names=array())
248     {
249         $fp = sugar_fopen(ImportCacheFiles::getDuplicateFileName(),'a');
250         fputcsv($fp, $this->_currentRow);
251         fclose($fp);
252
253         //if available, grab the column number based on passed in field_name
254         if(!empty($field_names))
255         {
256             $colkey = '';
257             $colnums = array();
258
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)
262             {
263                 $fv = trim($fv);
264                 if(empty($fv) || $fv == 'delete')
265                     continue;
266                 $new_keys = array_keys($_REQUEST, $fv);
267                 $colnums = array_merge($colnums,$new_keys);
268             }
269
270
271             //if values were found, process for number position
272             if(!empty($colnums))
273             {
274                 //foreach column, strip the 'colnum_' prefix to the get the column key value
275                 foreach($colnums as $column_key)
276                 {
277                     if(strpos($column_key,'colnum_') === 0)
278                     {
279                         $colkey = substr($column_key,7);
280                     }
281
282                     //if we have the column key, then lets add a span tag with styling reference to the original value
283                     if(!empty($colkey))
284                     {
285                         $hilited_val = $this->_currentRow[$colkey];
286                         $this->_currentRow[$colkey]= '<span class=warn>'.$hilited_val.'</span>';
287                     }
288                 }
289             }
290         }
291
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);
295         fclose($fdp);
296
297         //increment dupecount
298         $this->_dupeCount++;
299     }
300
301     /**
302      * Marks whether this row created a new record or not
303      *
304      * @param $createdRecord bool true if record is created, false if it is just updated
305      */
306     public function markRowAsImported($createdRecord = true)
307     {
308         if ( $createdRecord )
309             ++$this->_createdCount;
310         else
311             ++$this->_updatedCount;
312     }
313
314     /**
315      * Writes the row out to the ImportCacheFiles::getErrorRecordsFileName() file
316      */
317     public function writeErrorRecord($errorMessage = '')
318     {
319         $rowData = !$this->_currentRow ? array() : $this->_currentRow;
320         $fp = sugar_fopen(ImportCacheFiles::getErrorRecordsFileName(),'a');
321         $fpNoErrors = sugar_fopen(ImportCacheFiles::getErrorRecordsWithoutErrorFileName(),'a');
322
323         //Write records only for download without error message.
324         fputcsv($fpNoErrors, $rowData);
325
326         //Add the error message to the first column
327         array_unshift($rowData, $errorMessage);
328         fputcsv($fp, $rowData);
329         
330         fclose($fp);
331         fclose($fpNoErrors);
332     }
333
334     public function __get($var)
335     {
336         if( isset($_REQUEST[$var]) )
337             return $_REQUEST[$var];
338         else if( isset($this->_localeSettings[$var]) )
339             return $this->_localeSettings[$var];
340         else
341             return $this->$var;
342     }
343     
344 }
345