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