Commit | Line | Data |
---|---|---|
6a488035 TO |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
4 | | CiviCRM version 4.3 | | |
5 | +--------------------------------------------------------------------+ | |
6 | | Copyright CiviCRM LLC (c) 2004-2013 | | |
7 | +--------------------------------------------------------------------+ | |
8 | | This file is a part of CiviCRM. | | |
9 | | | | |
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. | | |
13 | | | | |
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. | | |
18 | | | | |
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 | +--------------------------------------------------------------------+ | |
26 | */ | |
27 | ||
28 | /** | |
29 | * | |
30 | * @package CRM | |
31 | * @copyright CiviCRM LLC (c) 2004-2013 | |
32 | * $Id$ | |
33 | * | |
34 | */ | |
35 | ||
36 | /** | |
37 | * This class acts like a psuedo-BAO for transient import job tables | |
38 | */ | |
39 | class CRM_Import_ImportJob { | |
40 | ||
41 | protected $_tableName; | |
42 | protected $_primaryKeyName; | |
43 | protected $_statusFieldName; | |
44 | ||
45 | protected $_doGeocodeAddress; | |
46 | protected $_invalidRowCount; | |
47 | protected $_conflictRowCount; | |
48 | protected $_onDuplicate; | |
49 | protected $_dedupe; | |
50 | protected $_newGroupName; | |
51 | protected $_newGroupDesc; | |
52 | protected $_groups; | |
53 | protected $_allGroups; | |
54 | protected $_newTagName; | |
55 | protected $_newTagDesc; | |
56 | protected $_tag; | |
57 | protected $_allTags; | |
58 | ||
59 | protected $_mapper; | |
60 | protected $_mapperKeys; | |
61 | protected $_mapperLocTypes; | |
62 | protected $_mapperPhoneTypes; | |
63 | protected $_mapperImProviders; | |
64 | protected $_mapperWebsiteTypes; | |
65 | protected $_mapperRelated; | |
66 | protected $_mapperRelatedContactType; | |
67 | protected $_mapperRelatedContactDetails; | |
68 | protected $_mapperRelatedContactLocType; | |
69 | protected $_mapperRelatedContactPhoneType; | |
70 | protected $_mapperRelatedContactImProvider; | |
71 | protected $_mapperRelatedContactWebsiteType; | |
72 | protected $_mapFields; | |
73 | ||
74 | protected $_parser; | |
75 | ||
76 | public function __construct($tableName = NULL, $createSql = NULL, $createTable = FALSE) { | |
77 | $dao = new CRM_Core_DAO(); | |
78 | $db = $dao->getDatabaseConnection(); | |
79 | ||
80 | if ($createTable) { | |
81 | if (!$createSql) { | |
82 | CRM_Core_Error::fatal('Either an existing table name or an SQL query to build one are required'); | |
83 | } | |
84 | ||
85 | // FIXME: we should regen this table's name if it exists rather than drop it | |
86 | if (!$tableName) { | |
87 | $tableName = 'civicrm_import_job_' . md5(uniqid(rand(), TRUE)); | |
88 | } | |
89 | $db->query("DROP TABLE IF EXISTS $tableName"); | |
90 | $db->query("CREATE TABLE $tableName ENGINE=InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci $createSql"); | |
91 | } | |
92 | ||
93 | if (!$tableName) { | |
94 | CRM_Core_Error::fatal('Import Table is required.'); | |
95 | } | |
96 | ||
97 | $this->_tableName = $tableName; | |
98 | ||
99 | //initialize the properties. | |
100 | $properties = array( | |
101 | 'mapperKeys', | |
102 | 'mapperRelated', | |
103 | 'mapperLocTypes', | |
104 | 'mapperPhoneTypes', | |
105 | 'mapperImProviders', | |
106 | 'mapperWebsiteTypes', | |
107 | 'mapperRelatedContactType', | |
108 | 'mapperRelatedContactDetails', | |
109 | 'mapperRelatedContactLocType', | |
110 | 'mapperRelatedContactPhoneType', | |
111 | 'mapperRelatedContactImProvider', | |
112 | 'mapperRelatedContactWebsiteType', | |
113 | ); | |
114 | foreach ($properties as $property) $this->{"_$property"} = array(); | |
115 | } | |
116 | ||
117 | public function getTableName() { | |
118 | return $this->_tableName; | |
119 | } | |
120 | ||
121 | public function isComplete($dropIfComplete = TRUE) { | |
122 | if (!$this->_statusFieldName) { | |
123 | CRM_Core_Error::fatal("Could not get name of the import status field"); | |
124 | } | |
125 | $query = "SELECT * FROM $this->_tableName | |
126 | WHERE $this->_statusFieldName = 'NEW' LIMIT 1"; | |
127 | $result = CRM_Core_DAO::executeQuery($query); | |
128 | if ($result->fetch()) { | |
129 | return FALSE; | |
130 | } | |
131 | if ($dropIfComplete) { | |
132 | $query = "DROP TABLE $this->_tableName"; | |
133 | CRM_Core_DAO::executeQuery($query); | |
134 | } | |
135 | return TRUE; | |
136 | } | |
137 | ||
138 | public function setJobParams(&$params) { | |
139 | foreach ($params as $param => $value) { | |
140 | eval("\$this->_$param = \$value;"); | |
141 | } | |
142 | } | |
143 | ||
144 | public function runImport(&$form, $timeout = 55) { | |
145 | $mapper = $this->_mapper; | |
146 | $mapperFields = array(); | |
147 | $phoneTypes = CRM_Core_PseudoConstant::phoneType(); | |
148 | $imProviders = CRM_Core_PseudoConstant::IMProvider(); | |
149 | $websiteTypes = CRM_Core_PseudoConstant::websiteType(); | |
150 | $locationTypes = CRM_Core_PseudoConstant::locationType(); | |
151 | ||
152 | //initialize mapper perperty value. | |
153 | $mapperPeroperties = array( | |
154 | 'mapperRelated' => 'mapperRelatedVal', | |
155 | 'mapperLocTypes' => 'mapperLocTypesVal', | |
156 | 'mapperPhoneTypes' => 'mapperPhoneTypesVal', | |
157 | 'mapperImProviders' => 'mapperImProvidersVal', | |
158 | 'mapperWebsiteTypes' => 'mapperWebsiteTypesVal', | |
159 | 'mapperRelatedContactType' => 'mapperRelatedContactTypeVal', | |
160 | 'mapperRelatedContactDetails' => 'mapperRelatedContactDetailsVal', | |
161 | 'mapperRelatedContactLocType' => 'mapperRelatedContactLocTypeVal', | |
162 | 'mapperRelatedContactPhoneType' => 'mapperRelatedContactPhoneTypeVal', | |
163 | 'mapperRelatedContactImProvider' => 'mapperRelatedContactImProviderVal', | |
164 | 'mapperRelatedContactWebsiteType' => 'mapperRelatedContactWebsiteTypeVal', | |
165 | ); | |
166 | ||
167 | foreach ($mapper as $key => $value) { | |
168 | //set respective mapper value to null. | |
169 | foreach (array_values($mapperPeroperties) as $perpertyVal)$$perpertyVal = NULL; | |
170 | ||
6a488035 | 171 | $fldName = CRM_Utils_Array::value(0, $mapper[$key]); |
4ba3ef8e | 172 | $header = array($this->_mapFields[$fldName]); |
6a488035 TO |
173 | $selOne = CRM_Utils_Array::value(1, $mapper[$key]); |
174 | $selTwo = CRM_Utils_Array::value(2, $mapper[$key]); | |
175 | $selThree = CRM_Utils_Array::value(3, $mapper[$key]); | |
176 | $this->_mapperKeys[$key] = $fldName; | |
177 | ||
178 | //need to differentiate non location elements. | |
179 | if ($selOne && is_numeric($selOne)) { | |
180 | if ($fldName == 'url') { | |
181 | $header[] = $websiteTypes[$selOne]; | |
182 | $mapperWebsiteTypesVal = $selOne; | |
183 | } | |
184 | else { | |
185 | $header[] = $locationTypes[$selOne]; | |
186 | $mapperLocTypesVal = $selOne; | |
187 | if ($selTwo && is_numeric($selTwo)) { | |
188 | if ($fldName == 'phone') { | |
189 | $header[] = $phoneTypes[$selTwo]; | |
190 | $mapperPhoneTypesVal = $selTwo; | |
191 | } | |
192 | elseif ($fldName == 'im') { | |
193 | $header[] = $imProviders[$selTwo]; | |
194 | $mapperImProvidersVal = $selTwo; | |
195 | } | |
196 | } | |
197 | } | |
198 | } | |
199 | ||
200 | $fldNameParts = explode('_', $fldName, 3); | |
201 | $id = $fldNameParts[0]; | |
202 | $first = isset($fldNameParts[1]) ? $fldNameParts[1] : NULL; | |
203 | $second = isset($fldNameParts[2]) ? $fldNameParts[2] : NULL; | |
204 | if (($first == 'a' && $second == 'b') || | |
205 | ($first == 'b' && $second == 'a') | |
206 | ) { | |
207 | ||
208 | $header[] = ucwords(str_replace("_", " ", $selOne)); | |
209 | ||
210 | $relationType = new CRM_Contact_DAO_RelationshipType(); | |
211 | $relationType->id = $id; | |
212 | $relationType->find(TRUE); | |
213 | $mapperRelatedContactTypeVal = $relationType->{"contact_type_$second"}; | |
214 | ||
215 | $mapperRelatedVal = $fldName; | |
216 | if ($selOne) { | |
217 | $mapperRelatedContactDetailsVal = $selOne; | |
218 | if ($selTwo) { | |
219 | if ($selOne == 'url') { | |
220 | $header[] = $websiteTypes[$selTwo]; | |
221 | $mapperRelatedContactWebsiteTypeVal = $selTwo; | |
222 | } | |
223 | else { | |
224 | $header[] = $locationTypes[$selTwo]; | |
225 | $mapperRelatedContactLocTypeVal = $selTwo; | |
226 | if ($selThree) { | |
227 | if ($selOne == 'phone') { | |
228 | $header[] = $phoneTypes[$selThree]; | |
229 | $mapperRelatedContactPhoneTypeVal = $selThree; | |
230 | } | |
231 | elseif ($selOne == 'im') { | |
232 | $header[] = $imProviders[$selThree]; | |
233 | $mapperRelatedContactImProviderVal = $selThree; | |
234 | } | |
235 | } | |
236 | } | |
237 | } | |
238 | } | |
239 | } | |
240 | $mapperFields[] = implode(' - ', $header); | |
241 | ||
242 | //set the respective mapper param array values. | |
243 | foreach ($mapperPeroperties as $mapperProKey => $mapperProVal) { | |
244 | $this->{"_$mapperProKey"}[$key] = $$mapperProVal; | |
245 | } | |
246 | } | |
247 | ||
248 | $this->_parser = new CRM_Import_Parser_Contact( | |
249 | $this->_mapperKeys, | |
250 | $this->_mapperLocTypes, | |
251 | $this->_mapperPhoneTypes, | |
252 | $this->_mapperImProviders, | |
253 | $this->_mapperRelated, | |
254 | $this->_mapperRelatedContactType, | |
255 | $this->_mapperRelatedContactDetails, | |
256 | $this->_mapperRelatedContactLocType, | |
257 | $this->_mapperRelatedContactPhoneType, | |
258 | $this->_mapperRelatedContactImProvider, | |
259 | $this->_mapperWebsiteTypes, | |
260 | $this->_mapperRelatedContactWebsiteType | |
261 | ); | |
262 | ||
263 | $this->_parser->run($this->_tableName, $mapperFields, | |
264 | CRM_Import_Parser::MODE_IMPORT, | |
265 | $this->_contactType, | |
266 | $this->_primaryKeyName, | |
267 | $this->_statusFieldName, | |
268 | $this->_onDuplicate, | |
269 | $this->_statusID, | |
270 | $this->_totalRowCount, | |
271 | $this->_doGeocodeAddress, | |
272 | CRM_Import_Parser::DEFAULT_TIMEOUT, | |
273 | $this->_contactSubType, | |
274 | $this->_dedupe | |
275 | ); | |
276 | ||
277 | $contactIds = $this->_parser->getImportedContacts(); | |
278 | ||
279 | //get the related contactIds. CRM-2926 | |
280 | $relatedContactIds = $this->_parser->getRelatedImportedContacts(); | |
281 | if ($relatedContactIds) { | |
282 | $contactIds = array_merge($contactIds, $relatedContactIds); | |
283 | if ($form) { | |
284 | $form->set('relatedCount', count($relatedContactIds)); | |
285 | } | |
286 | } | |
287 | ||
288 | if ($this->_newGroupName || count($this->_groups)) { | |
289 | $groupAdditions = $this->_addImportedContactsToNewGroup($contactIds, | |
290 | $this->_newGroupName, | |
291 | $this->_newGroupDesc | |
292 | ); | |
293 | if ($form) { | |
294 | $form->set('groupAdditions', $groupAdditions); | |
295 | } | |
296 | } | |
297 | ||
298 | if ($this->_newTagName || count($this->_tag)) { | |
299 | $tagAdditions = $this->_tagImportedContactsWithNewTag($contactIds, | |
300 | $this->_newTagName, | |
301 | $this->_newTagDesc | |
302 | ); | |
303 | if ($form) { | |
304 | $form->set('tagAdditions', $tagAdditions); | |
305 | } | |
306 | } | |
307 | } | |
308 | ||
309 | public function setFormVariables($form) { | |
310 | $this->_parser->set($form, CRM_Import_Parser::MODE_IMPORT); | |
311 | } | |
312 | ||
313 | private function _addImportedContactsToNewGroup($contactIds, | |
314 | $newGroupName, $newGroupDesc | |
315 | ) { | |
316 | ||
317 | $newGroupId = NULL; | |
318 | ||
319 | if ($newGroupName) { | |
320 | /* Create a new group */ | |
321 | ||
322 | $gParams = array( | |
323 | 'title' => $newGroupName, | |
324 | 'description' => $newGroupDesc, | |
325 | 'is_active' => TRUE, | |
326 | ); | |
327 | $group = CRM_Contact_BAO_Group::create($gParams); | |
328 | $this->_groups[] = $newGroupId = $group->id; | |
329 | } | |
330 | ||
331 | if (is_array($this->_groups)) { | |
332 | $groupAdditions = array(); | |
333 | foreach ($this->_groups as $groupId) { | |
334 | $addCount = CRM_Contact_BAO_GroupContact::addContactsToGroup($contactIds, $groupId); | |
335 | $totalCount = $addCount[1]; | |
336 | if ($groupId == $newGroupId) { | |
337 | $name = $newGroupName; | |
338 | $new = TRUE; | |
339 | } | |
340 | else { | |
341 | $name = $this->_allGroups[$groupId]; | |
342 | $new = FALSE; | |
343 | } | |
344 | $groupAdditions[] = array( | |
345 | 'url' => CRM_Utils_System::url('civicrm/group/search', | |
346 | 'reset=1&force=1&context=smog&gid=' . $groupId | |
347 | ), | |
348 | 'name' => $name, | |
349 | 'added' => $totalCount, | |
350 | 'notAdded' => $addCount[2], | |
351 | 'new' => $new, | |
352 | ); | |
353 | } | |
354 | return $groupAdditions; | |
355 | } | |
356 | return FALSE; | |
357 | } | |
358 | ||
359 | private function _tagImportedContactsWithNewTag($contactIds, | |
360 | $newTagName, $newTagDesc | |
361 | ) { | |
362 | ||
363 | $newTagId = NULL; | |
364 | if ($newTagName) { | |
365 | /* Create a new Tag */ | |
366 | ||
367 | $tagParams = array( | |
368 | 'name' => $newTagName, | |
369 | 'title' => $newTagName, | |
370 | 'description' => $newTagDesc, | |
371 | 'is_selectable' => TRUE, | |
372 | 'used_for' => 'civicrm_contact', | |
373 | ); | |
374 | $id = array(); | |
375 | $addedTag = CRM_Core_BAO_Tag::add($tagParams, $id); | |
376 | $this->_tag[$addedTag->id] = 1; | |
377 | } | |
378 | //add Tag to Import | |
379 | ||
380 | if (is_array($this->_tag)) { | |
381 | $tagAdditions = array(); | |
382 | foreach ($this->_tag as $tagId => $val) { | |
383 | $addTagCount = CRM_Core_BAO_EntityTag::addEntitiesToTag($contactIds, $tagId); | |
384 | $totalTagCount = $addTagCount[1]; | |
385 | if (isset($addedTag) && $tagId == $addedTag->id) { | |
386 | $tagName = $newTagName; | |
387 | $new = TRUE; | |
388 | } | |
389 | else { | |
390 | $tagName = $this->_allTags[$tagId]; | |
391 | $new = FALSE; | |
392 | } | |
393 | $tagAdditions[] = array( | |
394 | 'url' => CRM_Utils_System::url('civicrm/contact/search', | |
395 | 'reset=1&force=1&context=smog&id=' . $tagId | |
396 | ), | |
397 | 'name' => $tagName, | |
398 | 'added' => $totalTagCount, | |
399 | 'notAdded' => $addTagCount[2], | |
400 | 'new' => $new, | |
401 | ); | |
402 | } | |
403 | return $tagAdditions; | |
404 | } | |
405 | return FALSE; | |
406 | } | |
407 | ||
408 | public static function getIncompleteImportTables() { | |
409 | $dao = new CRM_Core_DAO(); | |
410 | $database = $dao->database(); | |
411 | $query = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA | |
412 | WHERE TABLE_SCHEMA = ? AND | |
413 | TABLE_NAME LIKE 'civicrm_import_job_%' | |
414 | ORDER BY TABLE_NAME"; | |
415 | $result = CRM_Core_DAO::executeQuery($query, array($database)); | |
416 | $incompleteImportTables = array(); | |
417 | while ($importTable = $result->fetch()) { | |
418 | if (!$this->isComplete($importTable)) { | |
419 | $incompleteImportTables[] = $importTable; | |
420 | } | |
421 | } | |
422 | return $incompleteImportTables; | |
423 | } | |
424 | } | |
425 |