749ec38478bec16043df0d516356a0588a710059
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.6 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2014
37 abstract class CRM_Import_Parser
{
41 const MAX_ERRORS
= 250, MAX_WARNINGS
= 25, DEFAULT_TIMEOUT
= 30;
46 const VALID
= 1, WARNING
= 2, ERROR
= 4, CONFLICT
= 8, STOP
= 16, DUPLICATE
= 32, MULTIPLE_DUPE
= 64, NO_MATCH
= 128, UNPARSED_ADDRESS_WARNING
= 256;
51 const MODE_MAPFIELD
= 1, MODE_PREVIEW
= 2, MODE_SUMMARY
= 4, MODE_IMPORT
= 8;
54 * Codes for duplicate record handling
56 const DUPLICATE_SKIP
= 1, DUPLICATE_REPLACE
= 2, DUPLICATE_UPDATE
= 4, DUPLICATE_FILL
= 8, DUPLICATE_NOCHECK
= 16;
61 const CONTACT_INDIVIDUAL
= 1, CONTACT_HOUSEHOLD
= 2, CONTACT_ORGANIZATION
= 4;
65 * Total number of non empty lines
67 protected $_totalCount;
70 * Running total number of valid lines
72 protected $_validCount;
75 * Running total number of invalid rows
77 protected $_invalidRowCount;
80 * Maximum number of non-empty/comment lines to process
84 protected $_maxLinesToProcess;
87 * Maximum number of invalid rows to store
89 protected $_maxErrorCount;
92 * Array of error lines, bounded by MAX_ERROR
97 * Total number of conflict lines
99 protected $_conflictCount;
102 * Array of conflict lines
104 protected $_conflicts;
107 * Total number of duplicate (from database) lines
109 protected $_duplicateCount;
112 * Array of duplicate lines
114 protected $_duplicates;
117 * Running total number of warnings
119 protected $_warningCount;
122 * Maximum number of warnings to store
124 protected $_maxWarningCount = self
::MAX_WARNINGS
;
127 * Array of warning lines, bounded by MAX_WARNING
129 protected $_warnings;
132 * Array of all the fields that could potentially be part
133 * of this import process
139 * Array of the fields that are actually part of the import process
140 * the position in the array also dictates their position in the import
144 protected $_activeFields;
147 * Cache the count of active fields
151 protected $_activeFieldCount;
154 * Cache of preview rows
161 * Filename of error data
165 protected $_errorFileName;
168 * Filename of conflict data
172 protected $_conflictFileName;
175 * Filename of duplicate data
179 protected $_duplicateFileName;
186 public $_contactType;
191 public function __construct() {
192 $this->_maxLinesToProcess
= 0;
193 $this->_maxErrorCount
= self
::MAX_ERRORS
;
197 * Abstract function definitions
199 abstract function init();
204 abstract function fini();
211 abstract function mapField(&$values);
218 abstract function preview(&$values);
225 abstract function summary(&$values);
228 * @param $onDuplicate
233 abstract function import($onDuplicate, &$values);
236 * Set and validate field values
238 * @param array $elements
240 * @param $erroneousField
245 public function setActiveFieldValues($elements, &$erroneousField) {
246 $maxCount = count($elements) < $this->_activeFieldCount ?
count($elements) : $this->_activeFieldCount
;
247 for ($i = 0; $i < $maxCount; $i++
) {
248 $this->_activeFields
[$i]->setValue($elements[$i]);
251 // reset all the values that we did not have an equivalent import element
252 for (; $i < $this->_activeFieldCount
; $i++
) {
253 $this->_activeFields
[$i]->resetValue();
256 // now validate the fields and return false if error
257 $valid = self
::VALID
;
258 for ($i = 0; $i < $this->_activeFieldCount
; $i++
) {
259 if (!$this->_activeFields
[$i]->validate()) {
260 // no need to do any more validation
261 $erroneousField = $i;
262 $valid = self
::ERROR
;
270 * Format the field values for input to the api
272 * @return array (reference) associative array of name/value pairs
274 public function &getActiveFieldParams() {
276 for ($i = 0; $i < $this->_activeFieldCount
; $i++
) {
277 if (isset($this->_activeFields
[$i]->_value
)
278 && !isset($params[$this->_activeFields
[$i]->_name
])
279 && !isset($this->_activeFields
[$i]->_related
)
282 $params[$this->_activeFields
[$i]->_name
] = $this->_activeFields
[$i]->_value
;
291 public function getSelectValues() {
293 foreach ($this->_fields
as $name => $field) {
294 $values[$name] = $field->_title
;
302 public function getSelectTypes() {
304 foreach ($this->_fields
as $name => $field) {
305 if (isset($field->_hasLocationType
)) {
306 $values[$name] = $field->_hasLocationType
;
315 public function getHeaderPatterns() {
317 foreach ($this->_fields
as $name => $field) {
318 if (isset($field->_headerPattern
)) {
319 $values[$name] = $field->_headerPattern
;
328 public function getDataPatterns() {
330 foreach ($this->_fields
as $name => $field) {
331 $values[$name] = $field->_dataPattern
;
337 * Remove single-quote enclosures from a value array (row)
339 * @param array $values
340 * @param string $enclosure
345 public static function encloseScrub(&$values, $enclosure = "'") {
346 if (empty($values)) {
350 foreach ($values as $k => $v) {
351 $values[$k] = preg_replace("/^$enclosure(.*)$enclosure$/", '$1', $v);
362 public function setMaxLinesToProcess($max) {
363 $this->_maxLinesToProcess
= $max;
367 * Determines the file extension based on error code
369 * @var $type error code constant
373 public static function errorFileName($type) {
379 $config = CRM_Core_Config
::singleton();
380 $fileName = $config->uploadDir
. "sqlImport";
383 $fileName .= '.errors';
387 $fileName .= '.conflicts';
390 case self
::DUPLICATE
:
391 $fileName .= '.duplicates';
395 $fileName .= '.mismatch';
398 case self
::UNPARSED_ADDRESS_WARNING
:
399 $fileName .= '.unparsedAddress';
407 * Determines the file name based on error code
409 * @var $type error code constant
413 public static function saveFileName($type) {
420 $fileName = 'Import_Errors.csv';
424 $fileName = 'Import_Conflicts.csv';
427 case self
::DUPLICATE
:
428 $fileName = 'Import_Duplicates.csv';
432 $fileName = 'Import_Mismatch.csv';
435 case self
::UNPARSED_ADDRESS_WARNING
:
436 $fileName = 'Import_Unparsed_Address.csv';