3 +--------------------------------------------------------------------+
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2019 |
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 2009 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-2019
35 * This class acts like a psuedo-BAO for transient import job tables.
37 class CRM_Contact_Import_ImportJob
{
39 protected $_tableName;
40 protected $_primaryKeyName;
41 protected $_statusFieldName;
43 protected $_doGeocodeAddress;
44 protected $_invalidRowCount;
45 protected $_conflictRowCount;
46 protected $_onDuplicate;
48 protected $_newGroupName;
49 protected $_newGroupDesc;
50 protected $_newGroupType;
52 protected $_allGroups;
53 protected $_newTagName;
54 protected $_newTagDesc;
59 protected $_mapperKeys = array();
60 protected $_mapFields;
65 * @param null $tableName
66 * @param null $createSql
67 * @param bool $createTable
71 public function __construct($tableName = NULL, $createSql = NULL, $createTable = FALSE) {
72 $dao = new CRM_Core_DAO();
73 $db = $dao->getDatabaseConnection();
77 CRM_Core_Error
::fatal('Either an existing table name or an SQL query to build one are required');
80 // FIXME: we should regen this table's name if it exists rather than drop it
82 $tableName = 'civicrm_import_job_' . md5(uniqid(rand(), TRUE));
84 $db->query("DROP TABLE IF EXISTS $tableName");
85 $db->query("CREATE TABLE $tableName ENGINE=InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci $createSql");
89 CRM_Core_Error
::fatal('Import Table is required.');
92 $this->_tableName
= $tableName;
98 public function getTableName() {
99 return $this->_tableName
;
103 * @param bool $dropIfComplete
108 public function isComplete($dropIfComplete = TRUE) {
109 if (!$this->_statusFieldName
) {
110 CRM_Core_Error
::fatal("Could not get name of the import status field");
112 $query = "SELECT * FROM $this->_tableName
113 WHERE $this->_statusFieldName = 'NEW' LIMIT 1";
114 $result = CRM_Core_DAO
::executeQuery($query);
115 if ($result->fetch()) {
118 if ($dropIfComplete) {
119 $query = "DROP TABLE $this->_tableName";
120 CRM_Core_DAO
::executeQuery($query);
126 * @param array $params
128 public function setJobParams(&$params) {
129 foreach ($params as $param => $value) {
130 $fldName = "_$param";
131 $this->$fldName = $value;
136 * @param CRM_Core_Form $form
137 * @param int $timeout
139 public function runImport(&$form, $timeout = 55) {
140 $mapper = $this->_mapper
;
141 $mapperFields = array();
142 $parserParameters = CRM_Contact_Import_Parser_Contact
::getParameterForParser(count($mapper));
143 $phoneTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Phone', 'phone_type_id');
144 $imProviders = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id');
145 $websiteTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Website', 'website_type_id');
146 $locationTypes = array('Primary' => ts('Primary')) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Address', 'location_type_id');
148 foreach ($mapper as $key => $value) {
150 $fldName = CRM_Utils_Array
::value(0, $mapper[$key]);
151 $header = array($this->_mapFields
[$fldName]);
152 $selOne = CRM_Utils_Array
::value(1, $mapper[$key]);
153 $selTwo = CRM_Utils_Array
::value(2, $mapper[$key]);
154 $selThree = CRM_Utils_Array
::value(3, $mapper[$key]);
155 $this->_mapperKeys
[$key] = $fldName;
157 //need to differentiate non location elements.
158 // @todo merge this with duplicate code on MapField class.
159 if ($selOne && (is_numeric($selOne) ||
$selOne === 'Primary')) {
160 if ($fldName == 'url') {
161 $header[] = $websiteTypes[$selOne];
162 $parserParameters['mapperWebsiteType'][$key] = $selOne;
165 $header[] = $locationTypes[$selOne];
166 $parserParameters['mapperLocType'][$key] = $selOne;
167 if ($selTwo && is_numeric($selTwo)) {
168 if ($fldName == 'phone') {
169 $header[] = $phoneTypes[$selTwo];
170 $parserParameters['mapperPhoneType'][$key] = $selTwo;
172 elseif ($fldName == 'im') {
173 $header[] = $imProviders[$selTwo];
174 $parserParameters['mapperImProvider'][$key] = $selTwo;
180 $fldNameParts = explode('_', $fldName, 3);
181 $id = $fldNameParts[0];
182 $first = isset($fldNameParts[1]) ?
$fldNameParts[1] : NULL;
183 $second = isset($fldNameParts[2]) ?
$fldNameParts[2] : NULL;
184 if (($first == 'a' && $second == 'b') ||
185 ($first == 'b' && $second == 'a')
188 $header[] = ucwords(str_replace("_", " ", $selOne));
190 $relationType = new CRM_Contact_DAO_RelationshipType();
191 $relationType->id
= $id;
192 $relationType->find(TRUE);
193 $parserParameters['relatedContactType'][$key] = $relationType->{"contact_type_$second"};
195 $parserParameters['mapperRelated'][$key] = $fldName;
197 $parserParameters['relatedContactDetails'][$key] = $selOne;
199 if ($selOne == 'url') {
200 $header[] = $websiteTypes[$selTwo];
201 $parserParameters[$key]['relatedContactWebsiteType'][$key] = $selTwo;
204 $header[] = $locationTypes[$selTwo];
205 $parserParameters['relatedContactLocType'][$key] = $selTwo;
207 if ($selOne == 'phone') {
208 $header[] = $phoneTypes[$selThree];
209 $parserParameters['relatedContactPhoneType'][$key] = $selThree;
211 elseif ($selOne == 'im') {
212 $header[] = $imProviders[$selThree];
213 $parserParameters['relatedContactImProvider'][$key] = $selThree;
220 $mapperFields[] = implode(' - ', $header);
223 $this->_parser
= new CRM_Contact_Import_Parser_Contact(
225 $parserParameters['mapperLocType'],
226 $parserParameters['mapperPhoneType'],
227 $parserParameters['mapperImProvider'],
228 $parserParameters['mapperRelated'],
229 $parserParameters['relatedContactType'],
230 $parserParameters['relatedContactDetails'],
231 $parserParameters['relatedContactLocType'],
232 $parserParameters['relatedContactPhoneType'],
233 $parserParameters['relatedContactImProvider'],
234 $parserParameters['mapperWebsiteType'],
235 $parserParameters['relatedContactWebsiteType']
238 $this->_parser
->run($this->_tableName
, $mapperFields,
239 CRM_Import_Parser
::MODE_IMPORT
,
241 $this->_primaryKeyName
,
242 $this->_statusFieldName
,
245 $this->_totalRowCount
,
246 $this->_doGeocodeAddress
,
247 CRM_Contact_Import_Parser
::DEFAULT_TIMEOUT
,
248 $this->_contactSubType
,
252 $contactIds = $this->_parser
->getImportedContacts();
254 //get the related contactIds. CRM-2926
255 $relatedContactIds = $this->_parser
->getRelatedImportedContacts();
256 if ($relatedContactIds) {
257 $contactIds = array_merge($contactIds, $relatedContactIds);
259 $form->set('relatedCount', count($relatedContactIds));
263 if ($this->_newGroupName ||
count($this->_groups
)) {
264 $groupAdditions = $this->_addImportedContactsToNewGroup($contactIds,
265 $this->_newGroupName
,
266 $this->_newGroupDesc
,
270 $form->set('groupAdditions', $groupAdditions);
274 if ($this->_newTagName ||
count($this->_tag
)) {
275 $tagAdditions = $this->_tagImportedContactsWithNewTag($contactIds,
280 $form->set('tagAdditions', $tagAdditions);
288 public function setFormVariables($form) {
289 $this->_parser
->set($form, CRM_Import_Parser
::MODE_IMPORT
);
293 * Add imported contacts.
295 * @param array $contactIds
296 * @param string $newGroupName
297 * @param string $newGroupDesc
298 * @param string $newGroupType
302 private function _addImportedContactsToNewGroup(
304 $newGroupName, $newGroupDesc, $newGroupType
310 /* Create a new group */
311 $newGroupType = isset($newGroupType) ?
$newGroupType : array();
313 'title' => $newGroupName,
314 'description' => $newGroupDesc,
315 'group_type' => $newGroupType,
318 $group = CRM_Contact_BAO_Group
::create($gParams);
319 $this->_groups
[] = $newGroupId = $group->id
;
322 if (is_array($this->_groups
)) {
323 $groupAdditions = array();
324 foreach ($this->_groups
as $groupId) {
325 $addCount = CRM_Contact_BAO_GroupContact
::addContactsToGroup($contactIds, $groupId);
326 $totalCount = $addCount[1];
327 if ($groupId == $newGroupId) {
328 $name = $newGroupName;
332 $name = $this->_allGroups
[$groupId];
335 $groupAdditions[] = array(
336 'url' => CRM_Utils_System
::url('civicrm/group/search',
337 'reset=1&force=1&context=smog&gid=' . $groupId
340 'added' => $totalCount,
341 'notAdded' => $addCount[2],
345 return $groupAdditions;
352 * @param string $newTagName
357 private function _tagImportedContactsWithNewTag(
359 $newTagName, $newTagDesc
364 /* Create a new Tag */
367 'name' => $newTagName,
368 'description' => $newTagDesc,
369 'is_selectable' => TRUE,
370 'used_for' => 'civicrm_contact',
373 $addedTag = CRM_Core_BAO_Tag
::add($tagParams, $id);
374 $this->_tag
[$addedTag->id
] = 1;
378 if (is_array($this->_tag
)) {
379 $tagAdditions = array();
380 foreach ($this->_tag
as $tagId => $val) {
381 $addTagCount = CRM_Core_BAO_EntityTag
::addEntitiesToTag($contactIds, $tagId, 'civicrm_contact', FALSE);
382 $totalTagCount = $addTagCount[1];
383 if (isset($addedTag) && $tagId == $addedTag->id
) {
384 $tagName = $newTagName;
388 $tagName = $this->_allTags
[$tagId];
391 $tagAdditions[] = array(
392 'url' => CRM_Utils_System
::url('civicrm/contact/search',
393 'reset=1&force=1&context=smog&id=' . $tagId
396 'added' => $totalTagCount,
397 'notAdded' => $addTagCount[2],
401 return $tagAdditions;
409 public static function getIncompleteImportTables() {
410 $dao = new CRM_Core_DAO();
411 $database = $dao->database();
412 $query = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA
413 WHERE TABLE_SCHEMA = ? AND
414 TABLE_NAME LIKE 'civicrm_import_job_%'
415 ORDER BY TABLE_NAME";
416 $result = CRM_Core_DAO
::executeQuery($query, array($database));
417 $incompleteImportTables = array();
418 while ($importTable = $result->fetch()) {
419 if (!$this->isComplete($importTable)) {
420 $incompleteImportTables[] = $importTable;
423 return $incompleteImportTables;