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