Commit | Line | Data |
---|---|---|
6a488035 TO |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
bc77d7c0 | 4 | | Copyright CiviCRM LLC. All rights reserved. | |
6a488035 | 5 | | | |
bc77d7c0 TO |
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 | | |
6a488035 | 9 | +--------------------------------------------------------------------+ |
d25dd0ee | 10 | */ |
6a488035 TO |
11 | |
12 | /** | |
13 | * | |
14 | * @package CRM | |
bc77d7c0 | 15 | * @copyright CiviCRM LLC https://civicrm.org/licensing |
6a488035 TO |
16 | */ |
17 | ||
18 | /** | |
616eac7e | 19 | * This class acts like a psuedo-BAO for transient import job tables. |
6a488035 | 20 | */ |
719a6fec | 21 | class CRM_Contact_Import_ImportJob { |
6a488035 TO |
22 | |
23 | protected $_tableName; | |
24 | protected $_primaryKeyName; | |
25 | protected $_statusFieldName; | |
26 | ||
27 | protected $_doGeocodeAddress; | |
28 | protected $_invalidRowCount; | |
29 | protected $_conflictRowCount; | |
30 | protected $_onDuplicate; | |
31 | protected $_dedupe; | |
32 | protected $_newGroupName; | |
33 | protected $_newGroupDesc; | |
5a552b87 | 34 | protected $_newGroupType; |
6a488035 TO |
35 | protected $_groups; |
36 | protected $_allGroups; | |
37 | protected $_newTagName; | |
38 | protected $_newTagDesc; | |
39 | protected $_tag; | |
40 | protected $_allTags; | |
41 | ||
42 | protected $_mapper; | |
affcc9d2 | 43 | protected $_mapperKeys = []; |
6a488035 TO |
44 | protected $_mapFields; |
45 | ||
46 | protected $_parser; | |
47 | ||
86538308 EM |
48 | /** |
49 | * @param null $tableName | |
50 | * @param null $createSql | |
51 | * @param bool $createTable | |
52 | * | |
2d296f18 | 53 | * @throws \CRM_Core_Exception |
86538308 | 54 | */ |
6a488035 TO |
55 | public function __construct($tableName = NULL, $createSql = NULL, $createTable = FALSE) { |
56 | $dao = new CRM_Core_DAO(); | |
57 | $db = $dao->getDatabaseConnection(); | |
58 | ||
59 | if ($createTable) { | |
60 | if (!$createSql) { | |
2d296f18 | 61 | throw new CRM_Core_Exception(ts('Either an existing table name or an SQL query to build one are required')); |
6a488035 | 62 | } |
c4382285 | 63 | if ($tableName) { |
64 | // Drop previous table if passed in and create new one. | |
65 | $db->query("DROP TABLE IF EXISTS $tableName"); | |
6a488035 | 66 | } |
c4382285 | 67 | $table = CRM_Utils_SQL_TempTable::build()->setDurable(); |
68 | $tableName = $table->getName(); | |
69 | $table->createWithQuery($createSql); | |
6a488035 TO |
70 | } |
71 | ||
72 | if (!$tableName) { | |
2d296f18 | 73 | throw new CRM_Core_Exception(ts('Import Table is required.')); |
6a488035 TO |
74 | } |
75 | ||
76 | $this->_tableName = $tableName; | |
6a488035 TO |
77 | } |
78 | ||
86538308 EM |
79 | /** |
80 | * @return null|string | |
81 | */ | |
6a488035 TO |
82 | public function getTableName() { |
83 | return $this->_tableName; | |
84 | } | |
85 | ||
86538308 EM |
86 | /** |
87 | * @param bool $dropIfComplete | |
88 | * | |
89 | * @return bool | |
90 | * @throws Exception | |
91 | */ | |
6a488035 TO |
92 | public function isComplete($dropIfComplete = TRUE) { |
93 | if (!$this->_statusFieldName) { | |
7980012b | 94 | throw new CRM_Core_Exception("Could not get name of the import status field"); |
6a488035 TO |
95 | } |
96 | $query = "SELECT * FROM $this->_tableName | |
97 | WHERE $this->_statusFieldName = 'NEW' LIMIT 1"; | |
98 | $result = CRM_Core_DAO::executeQuery($query); | |
99 | if ($result->fetch()) { | |
100 | return FALSE; | |
101 | } | |
102 | if ($dropIfComplete) { | |
103 | $query = "DROP TABLE $this->_tableName"; | |
104 | CRM_Core_DAO::executeQuery($query); | |
105 | } | |
106 | return TRUE; | |
107 | } | |
108 | ||
86538308 | 109 | /** |
c490a46a | 110 | * @param array $params |
86538308 | 111 | */ |
6a488035 TO |
112 | public function setJobParams(&$params) { |
113 | foreach ($params as $param => $value) { | |
0e6e8724 DL |
114 | $fldName = "_$param"; |
115 | $this->$fldName = $value; | |
6a488035 TO |
116 | } |
117 | } | |
118 | ||
86538308 | 119 | /** |
c490a46a | 120 | * @param CRM_Core_Form $form |
86538308 EM |
121 | * @param int $timeout |
122 | */ | |
6a488035 | 123 | public function runImport(&$form, $timeout = 55) { |
353ffa53 | 124 | $mapper = $this->_mapper; |
affcc9d2 | 125 | $mapperFields = []; |
1881b7b0 | 126 | $parserParameters = CRM_Contact_Import_Parser_Contact::getParameterForParser(count($mapper)); |
353ffa53 TO |
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'); | |
28557f54 | 130 | $locationTypes = array('Primary' => ts('Primary')) + CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id'); |
6a488035 | 131 | |
6a488035 | 132 | foreach ($mapper as $key => $value) { |
6a488035 | 133 | |
9c1bc317 | 134 | $fldName = $mapper[$key][0] ?? NULL; |
4ba3ef8e | 135 | $header = array($this->_mapFields[$fldName]); |
9c1bc317 CW |
136 | $selOne = $mapper[$key][1] ?? NULL; |
137 | $selTwo = $mapper[$key][2] ?? NULL; | |
138 | $selThree = $mapper[$key][3] ?? NULL; | |
6a488035 TO |
139 | $this->_mapperKeys[$key] = $fldName; |
140 | ||
141 | //need to differentiate non location elements. | |
6ebecfea | 142 | // @todo merge this with duplicate code on MapField class. |
143 | if ($selOne && (is_numeric($selOne) || $selOne === 'Primary')) { | |
0a66a182 | 144 | if ($fldName === 'url') { |
6a488035 | 145 | $header[] = $websiteTypes[$selOne]; |
1881b7b0 | 146 | $parserParameters['mapperWebsiteType'][$key] = $selOne; |
6a488035 TO |
147 | } |
148 | else { | |
149 | $header[] = $locationTypes[$selOne]; | |
1881b7b0 | 150 | $parserParameters['mapperLocType'][$key] = $selOne; |
6a488035 | 151 | if ($selTwo && is_numeric($selTwo)) { |
0a66a182 | 152 | if ($fldName === 'phone') { |
6a488035 | 153 | $header[] = $phoneTypes[$selTwo]; |
1881b7b0 | 154 | $parserParameters['mapperPhoneType'][$key] = $selTwo; |
6a488035 | 155 | } |
0a66a182 | 156 | elseif ($fldName === 'im') { |
6a488035 | 157 | $header[] = $imProviders[$selTwo]; |
1881b7b0 | 158 | $parserParameters['mapperImProvider'][$key] = $selTwo; |
6a488035 TO |
159 | } |
160 | } | |
161 | } | |
162 | } | |
163 | ||
164 | $fldNameParts = explode('_', $fldName, 3); | |
353ffa53 | 165 | $id = $fldNameParts[0]; |
2e1f50d6 CW |
166 | $first = $fldNameParts[1] ?? NULL; |
167 | $second = $fldNameParts[2] ?? NULL; | |
6a488035 TO |
168 | if (($first == 'a' && $second == 'b') || |
169 | ($first == 'b' && $second == 'a') | |
170 | ) { | |
171 | ||
172 | $header[] = ucwords(str_replace("_", " ", $selOne)); | |
173 | ||
174 | $relationType = new CRM_Contact_DAO_RelationshipType(); | |
175 | $relationType->id = $id; | |
176 | $relationType->find(TRUE); | |
1881b7b0 | 177 | $parserParameters['relatedContactType'][$key] = $relationType->{"contact_type_$second"}; |
6a488035 | 178 | |
1881b7b0 | 179 | $parserParameters['mapperRelated'][$key] = $fldName; |
6a488035 | 180 | if ($selOne) { |
1881b7b0 | 181 | $parserParameters['relatedContactDetails'][$key] = $selOne; |
6a488035 TO |
182 | if ($selTwo) { |
183 | if ($selOne == 'url') { | |
184 | $header[] = $websiteTypes[$selTwo]; | |
1881b7b0 | 185 | $parserParameters[$key]['relatedContactWebsiteType'][$key] = $selTwo; |
6a488035 TO |
186 | } |
187 | else { | |
188 | $header[] = $locationTypes[$selTwo]; | |
1881b7b0 | 189 | $parserParameters['relatedContactLocType'][$key] = $selTwo; |
6a488035 TO |
190 | if ($selThree) { |
191 | if ($selOne == 'phone') { | |
192 | $header[] = $phoneTypes[$selThree]; | |
1881b7b0 | 193 | $parserParameters['relatedContactPhoneType'][$key] = $selThree; |
6a488035 TO |
194 | } |
195 | elseif ($selOne == 'im') { | |
196 | $header[] = $imProviders[$selThree]; | |
1881b7b0 | 197 | $parserParameters['relatedContactImProvider'][$key] = $selThree; |
6a488035 TO |
198 | } |
199 | } | |
200 | } | |
201 | } | |
202 | } | |
203 | } | |
204 | $mapperFields[] = implode(' - ', $header); | |
6a488035 TO |
205 | } |
206 | ||
719a6fec | 207 | $this->_parser = new CRM_Contact_Import_Parser_Contact( |
6a488035 | 208 | $this->_mapperKeys, |
1881b7b0 | 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'] | |
6a488035 TO |
220 | ); |
221 | ||
222 | $this->_parser->run($this->_tableName, $mapperFields, | |
a05662ef | 223 | CRM_Import_Parser::MODE_IMPORT, |
6a488035 TO |
224 | $this->_contactType, |
225 | $this->_primaryKeyName, | |
226 | $this->_statusFieldName, | |
227 | $this->_onDuplicate, | |
228 | $this->_statusID, | |
229 | $this->_totalRowCount, | |
230 | $this->_doGeocodeAddress, | |
719a6fec | 231 | CRM_Contact_Import_Parser::DEFAULT_TIMEOUT, |
6a488035 TO |
232 | $this->_contactSubType, |
233 | $this->_dedupe | |
234 | ); | |
235 | ||
236 | $contactIds = $this->_parser->getImportedContacts(); | |
237 | ||
238 | //get the related contactIds. CRM-2926 | |
239 | $relatedContactIds = $this->_parser->getRelatedImportedContacts(); | |
240 | if ($relatedContactIds) { | |
241 | $contactIds = array_merge($contactIds, $relatedContactIds); | |
242 | if ($form) { | |
243 | $form->set('relatedCount', count($relatedContactIds)); | |
244 | } | |
245 | } | |
246 | ||
247 | if ($this->_newGroupName || count($this->_groups)) { | |
248 | $groupAdditions = $this->_addImportedContactsToNewGroup($contactIds, | |
249 | $this->_newGroupName, | |
5a552b87 SL |
250 | $this->_newGroupDesc, |
251 | $this->_newGroupType | |
6a488035 TO |
252 | ); |
253 | if ($form) { | |
254 | $form->set('groupAdditions', $groupAdditions); | |
255 | } | |
256 | } | |
257 | ||
f547eb3a | 258 | if ($this->_newTagName || !empty($this->_tag)) { |
6a488035 TO |
259 | $tagAdditions = $this->_tagImportedContactsWithNewTag($contactIds, |
260 | $this->_newTagName, | |
261 | $this->_newTagDesc | |
262 | ); | |
263 | if ($form) { | |
264 | $form->set('tagAdditions', $tagAdditions); | |
265 | } | |
266 | } | |
267 | } | |
268 | ||
86538308 EM |
269 | /** |
270 | * @param $form | |
271 | */ | |
6a488035 | 272 | public function setFormVariables($form) { |
a05662ef | 273 | $this->_parser->set($form, CRM_Import_Parser::MODE_IMPORT); |
6a488035 TO |
274 | } |
275 | ||
86538308 | 276 | /** |
dbb0d30b | 277 | * Add imported contacts. |
278 | * | |
279 | * @param array $contactIds | |
100fef9d | 280 | * @param string $newGroupName |
dbb0d30b | 281 | * @param string $newGroupDesc |
282 | * @param string $newGroupType | |
86538308 EM |
283 | * |
284 | * @return array|bool | |
285 | */ | |
51ccfbbe TO |
286 | private function _addImportedContactsToNewGroup( |
287 | $contactIds, | |
5a552b87 | 288 | $newGroupName, $newGroupDesc, $newGroupType |
6a488035 TO |
289 | ) { |
290 | ||
291 | $newGroupId = NULL; | |
292 | ||
293 | if ($newGroupName) { | |
294 | /* Create a new group */ | |
affcc9d2 | 295 | $newGroupType = $newGroupType ?? []; |
6a488035 TO |
296 | $gParams = array( |
297 | 'title' => $newGroupName, | |
298 | 'description' => $newGroupDesc, | |
5a552b87 | 299 | 'group_type' => $newGroupType, |
6a488035 TO |
300 | 'is_active' => TRUE, |
301 | ); | |
302 | $group = CRM_Contact_BAO_Group::create($gParams); | |
303 | $this->_groups[] = $newGroupId = $group->id; | |
304 | } | |
305 | ||
306 | if (is_array($this->_groups)) { | |
affcc9d2 | 307 | $groupAdditions = []; |
6a488035 TO |
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; | |
313 | $new = TRUE; | |
314 | } | |
315 | else { | |
316 | $name = $this->_allGroups[$groupId]; | |
317 | $new = FALSE; | |
318 | } | |
319 | $groupAdditions[] = array( | |
320 | 'url' => CRM_Utils_System::url('civicrm/group/search', | |
321 | 'reset=1&force=1&context=smog&gid=' . $groupId | |
322 | ), | |
323 | 'name' => $name, | |
324 | 'added' => $totalCount, | |
325 | 'notAdded' => $addCount[2], | |
326 | 'new' => $new, | |
327 | ); | |
328 | } | |
329 | return $groupAdditions; | |
330 | } | |
331 | return FALSE; | |
332 | } | |
333 | ||
86538308 EM |
334 | /** |
335 | * @param $contactIds | |
100fef9d | 336 | * @param string $newTagName |
86538308 EM |
337 | * @param $newTagDesc |
338 | * | |
339 | * @return array|bool | |
0a66a182 | 340 | * @throws \CRM_Core_Exception |
86538308 | 341 | */ |
51ccfbbe TO |
342 | private function _tagImportedContactsWithNewTag( |
343 | $contactIds, | |
6a488035 TO |
344 | $newTagName, $newTagDesc |
345 | ) { | |
346 | ||
347 | $newTagId = NULL; | |
348 | if ($newTagName) { | |
349 | /* Create a new Tag */ | |
350 | ||
351 | $tagParams = array( | |
352 | 'name' => $newTagName, | |
6a488035 TO |
353 | 'description' => $newTagDesc, |
354 | 'is_selectable' => TRUE, | |
355 | 'used_for' => 'civicrm_contact', | |
356 | ); | |
3a839de8 | 357 | $addedTag = CRM_Core_BAO_Tag::add($tagParams); |
6a488035 TO |
358 | $this->_tag[$addedTag->id] = 1; |
359 | } | |
360 | //add Tag to Import | |
361 | ||
362 | if (is_array($this->_tag)) { | |
affcc9d2 | 363 | $tagAdditions = []; |
6a488035 | 364 | foreach ($this->_tag as $tagId => $val) { |
424616b8 | 365 | $addTagCount = CRM_Core_BAO_EntityTag::addEntitiesToTag($contactIds, $tagId, 'civicrm_contact', FALSE); |
6a488035 TO |
366 | $totalTagCount = $addTagCount[1]; |
367 | if (isset($addedTag) && $tagId == $addedTag->id) { | |
368 | $tagName = $newTagName; | |
369 | $new = TRUE; | |
370 | } | |
371 | else { | |
372 | $tagName = $this->_allTags[$tagId]; | |
373 | $new = FALSE; | |
374 | } | |
375 | $tagAdditions[] = array( | |
376 | 'url' => CRM_Utils_System::url('civicrm/contact/search', | |
377 | 'reset=1&force=1&context=smog&id=' . $tagId | |
378 | ), | |
379 | 'name' => $tagName, | |
380 | 'added' => $totalTagCount, | |
381 | 'notAdded' => $addTagCount[2], | |
382 | 'new' => $new, | |
383 | ); | |
384 | } | |
385 | return $tagAdditions; | |
386 | } | |
387 | return FALSE; | |
388 | } | |
389 | ||
6a488035 | 390 | } |