3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
19 * This class acts like a psuedo-BAO for transient import job tables.
21 class CRM_Contact_Import_ImportJob
{
23 protected $_tableName;
24 protected $_primaryKeyName;
25 protected $_statusFieldName;
27 protected $_doGeocodeAddress;
28 protected $_invalidRowCount;
29 protected $_conflictRowCount;
30 protected $_onDuplicate;
32 protected $_newGroupName;
33 protected $_newGroupDesc;
34 protected $_newGroupType;
36 protected $_allGroups;
37 protected $_newTagName;
38 protected $_newTagDesc;
43 protected $_mapperKeys = [];
44 protected $_mapFields;
49 * @param string|null $tableName
50 * @param string|null $createSql
51 * @param bool $createTable
53 * @throws \CRM_Core_Exception
55 public function __construct($tableName = NULL, $createSql = NULL, $createTable = FALSE) {
56 $dao = new CRM_Core_DAO();
57 $db = $dao->getDatabaseConnection();
61 throw new CRM_Core_Exception(ts('Either an existing table name or an SQL query to build one are required'));
64 // Drop previous table if passed in and create new one.
65 $db->query("DROP TABLE IF EXISTS $tableName");
67 $table = CRM_Utils_SQL_TempTable
::build()->setDurable();
68 $tableName = $table->getName();
69 $table->createWithQuery($createSql);
73 throw new CRM_Core_Exception(ts('Import Table is required.'));
76 $this->_tableName
= $tableName;
82 public function getTableName() {
83 return $this->_tableName
;
87 * @param bool $dropIfComplete
92 public function isComplete($dropIfComplete = TRUE) {
93 if (!$this->_statusFieldName
) {
94 throw new CRM_Core_Exception("Could not get name of the import status field");
96 $query = "SELECT * FROM $this->_tableName
97 WHERE $this->_statusFieldName = 'NEW' LIMIT 1";
98 $result = CRM_Core_DAO
::executeQuery($query);
99 if ($result->fetch()) {
102 if ($dropIfComplete) {
103 $query = "DROP TABLE $this->_tableName";
104 CRM_Core_DAO
::executeQuery($query);
110 * @param array $params
112 public function setJobParams(&$params) {
113 foreach ($params as $param => $value) {
114 $fldName = "_$param";
115 $this->$fldName = $value;
120 * @param CRM_Core_Form $form
121 * @param int $timeout
123 public function runImport(&$form, $timeout = 55) {
124 $mapper = $this->_mapper
;
126 $parserParameters = CRM_Contact_Import_Parser_Contact
::getParameterForParser(count($mapper));
127 $phoneTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Phone', 'phone_type_id');
128 $imProviders = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id');
129 $websiteTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Website', 'website_type_id');
130 $locationTypes = array('Primary' => ts('Primary')) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Address', 'location_type_id');
132 foreach ($mapper as $key => $value) {
134 $fldName = $mapper[$key][0] ??
NULL;
135 $header = array($this->_mapFields
[$fldName]);
136 $selOne = $mapper[$key][1] ??
NULL;
137 $selTwo = $mapper[$key][2] ??
NULL;
138 $selThree = $mapper[$key][3] ??
NULL;
139 $this->_mapperKeys
[$key] = $fldName;
141 //need to differentiate non location elements.
142 // @todo merge this with duplicate code on MapField class.
143 if ($selOne && (is_numeric($selOne) ||
$selOne === 'Primary')) {
144 if ($fldName === 'url') {
145 $header[] = $websiteTypes[$selOne];
146 $parserParameters['mapperWebsiteType'][$key] = $selOne;
149 $header[] = $locationTypes[$selOne];
150 $parserParameters['mapperLocType'][$key] = $selOne;
151 if ($selTwo && is_numeric($selTwo)) {
152 if ($fldName === 'phone' ||
$fldName === 'phone_ext') {
153 $header[] = $phoneTypes[$selTwo];
154 $parserParameters['mapperPhoneType'][$key] = $selTwo;
156 elseif ($fldName === 'im') {
157 $header[] = $imProviders[$selTwo];
158 $parserParameters['mapperImProvider'][$key] = $selTwo;
164 $fldNameParts = explode('_', $fldName, 3);
165 $id = $fldNameParts[0];
166 $first = $fldNameParts[1] ??
NULL;
167 $second = $fldNameParts[2] ??
NULL;
168 if (($first == 'a' && $second == 'b') ||
169 ($first == 'b' && $second == 'a')
172 $header[] = ucwords(str_replace("_", " ", $selOne));
174 $relationType = new CRM_Contact_DAO_RelationshipType();
175 $relationType->id
= $id;
176 $relationType->find(TRUE);
177 $parserParameters['relatedContactType'][$key] = $relationType->{"contact_type_$second"};
179 $parserParameters['mapperRelated'][$key] = $fldName;
181 $parserParameters['relatedContactDetails'][$key] = $selOne;
183 if ($selOne == 'url') {
184 $header[] = $websiteTypes[$selTwo];
185 $parserParameters[$key]['relatedContactWebsiteType'][$key] = $selTwo;
188 $header[] = $locationTypes[$selTwo];
189 $parserParameters['relatedContactLocType'][$key] = $selTwo;
191 if ($selOne == 'phone' ||
$selOne == 'phone_ext') {
192 $header[] = $phoneTypes[$selThree];
193 $parserParameters['relatedContactPhoneType'][$key] = $selThree;
195 elseif ($selOne == 'im') {
196 $header[] = $imProviders[$selThree];
197 $parserParameters['relatedContactImProvider'][$key] = $selThree;
204 $mapperFields[] = implode(' - ', $header);
207 $this->_parser
= new CRM_Contact_Import_Parser_Contact(
209 $parserParameters['mapperLocType'],
210 $parserParameters['mapperPhoneType'],
211 $parserParameters['mapperImProvider'],
212 $parserParameters['mapperRelated'],
213 $parserParameters['relatedContactType'],
214 $parserParameters['relatedContactDetails'],
215 $parserParameters['relatedContactLocType'],
216 $parserParameters['relatedContactPhoneType'],
217 $parserParameters['relatedContactImProvider'],
218 $parserParameters['mapperWebsiteType'],
219 $parserParameters['relatedContactWebsiteType']
222 $this->_parser
->run($this->_tableName
, $mapperFields,
223 CRM_Import_Parser
::MODE_IMPORT
,
225 $this->_primaryKeyName
,
226 $this->_statusFieldName
,
229 $this->_totalRowCount
,
230 $this->_doGeocodeAddress
,
231 CRM_Contact_Import_Parser_Contact
::DEFAULT_TIMEOUT
,
232 $this->_contactSubType
,
236 $contactIds = $this->_parser
->getImportedContacts();
238 //get the related contactIds. CRM-2926
239 $relatedContactIds = $this->_parser
->getRelatedImportedContacts();
240 if ($relatedContactIds) {
241 $contactIds = array_merge($contactIds, $relatedContactIds);
243 $form->set('relatedCount', count($relatedContactIds));
247 if ($this->_newGroupName ||
count($this->_groups
)) {
248 $groupAdditions = $this->_addImportedContactsToNewGroup($contactIds,
249 $this->_newGroupName
,
250 $this->_newGroupDesc
,
254 $form->set('groupAdditions', $groupAdditions);
258 if ($this->_newTagName ||
!empty($this->_tag
)) {
259 $tagAdditions = $this->_tagImportedContactsWithNewTag($contactIds,
264 $form->set('tagAdditions', $tagAdditions);
272 public function setFormVariables($form) {
273 $this->_parser
->set($form, CRM_Import_Parser
::MODE_IMPORT
);
277 * Add imported contacts.
279 * @param array $contactIds
280 * @param string $newGroupName
281 * @param string $newGroupDesc
282 * @param string $newGroupType
286 private function _addImportedContactsToNewGroup(
288 $newGroupName, $newGroupDesc, $newGroupType
294 /* Create a new group */
295 $newGroupType = $newGroupType ??
[];
297 'title' => $newGroupName,
298 'description' => $newGroupDesc,
299 'group_type' => $newGroupType,
302 $group = CRM_Contact_BAO_Group
::create($gParams);
303 $this->_groups
[] = $newGroupId = $group->id
;
306 if (is_array($this->_groups
)) {
307 $groupAdditions = [];
308 foreach ($this->_groups
as $groupId) {
309 $addCount = CRM_Contact_BAO_GroupContact
::addContactsToGroup($contactIds, $groupId);
310 $totalCount = $addCount[1];
311 if ($groupId == $newGroupId) {
312 $name = $newGroupName;
316 $name = $this->_allGroups
[$groupId];
319 $groupAdditions[] = array(
320 'url' => CRM_Utils_System
::url('civicrm/group/search',
321 'reset=1&force=1&context=smog&gid=' . $groupId
324 'added' => $totalCount,
325 'notAdded' => $addCount[2],
329 return $groupAdditions;
336 * @param string $newTagName
340 * @throws \CRM_Core_Exception
342 private function _tagImportedContactsWithNewTag(
344 $newTagName, $newTagDesc
349 /* Create a new Tag */
352 'name' => $newTagName,
353 'description' => $newTagDesc,
354 'is_selectable' => TRUE,
355 'used_for' => 'civicrm_contact',
357 $addedTag = CRM_Core_BAO_Tag
::add($tagParams);
358 $this->_tag
[$addedTag->id
] = 1;
362 if (is_array($this->_tag
)) {
364 foreach ($this->_tag
as $tagId => $val) {
365 $addTagCount = CRM_Core_BAO_EntityTag
::addEntitiesToTag($contactIds, $tagId, 'civicrm_contact', FALSE);
366 $totalTagCount = $addTagCount[1];
367 if (isset($addedTag) && $tagId == $addedTag->id
) {
368 $tagName = $newTagName;
372 $tagName = $this->_allTags
[$tagId];
375 $tagAdditions[] = array(
376 'url' => CRM_Utils_System
::url('civicrm/contact/search',
377 'reset=1&force=1&context=smog&id=' . $tagId
380 'added' => $totalTagCount,
381 'notAdded' => $addTagCount[2],
385 return $tagAdditions;