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
21 * This class acts like a psuedo-BAO for transient import job tables.
23 class CRM_Contact_Import_ImportJob
{
25 protected $_tableName;
26 protected $_primaryKeyName;
27 protected $_statusFieldName;
29 protected $_doGeocodeAddress;
30 protected $_invalidRowCount;
31 protected $_conflictRowCount;
32 protected $_onDuplicate;
34 protected $_newGroupName;
35 protected $_newGroupDesc;
36 protected $_newGroupType;
38 protected $_allGroups;
39 protected $_newTagName;
40 protected $_newTagDesc;
45 protected $_mapperKeys = array();
46 protected $_mapFields;
51 * @param null $tableName
52 * @param null $createSql
53 * @param bool $createTable
57 public function __construct($tableName = NULL, $createSql = NULL, $createTable = FALSE) {
58 $dao = new CRM_Core_DAO();
59 $db = $dao->getDatabaseConnection();
63 CRM_Core_Error
::fatal('Either an existing table name or an SQL query to build one are required');
66 // FIXME: we should regen this table's name if it exists rather than drop it
68 $tableName = 'civicrm_import_job_' . md5(uniqid(rand(), TRUE));
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");
75 CRM_Core_Error
::fatal('Import Table is required.');
78 $this->_tableName
= $tableName;
84 public function getTableName() {
85 return $this->_tableName
;
89 * @param bool $dropIfComplete
94 public function isComplete($dropIfComplete = TRUE) {
95 if (!$this->_statusFieldName
) {
96 CRM_Core_Error
::fatal("Could not get name of the import status field");
98 $query = "SELECT * FROM $this->_tableName
99 WHERE $this->_statusFieldName = 'NEW' LIMIT 1";
100 $result = CRM_Core_DAO
::executeQuery($query);
101 if ($result->fetch()) {
104 if ($dropIfComplete) {
105 $query = "DROP TABLE $this->_tableName";
106 CRM_Core_DAO
::executeQuery($query);
112 * @param array $params
114 public function setJobParams(&$params) {
115 foreach ($params as $param => $value) {
116 $fldName = "_$param";
117 $this->$fldName = $value;
122 * @param CRM_Core_Form $form
123 * @param int $timeout
125 public function runImport(&$form, $timeout = 55) {
126 $mapper = $this->_mapper
;
127 $mapperFields = array();
128 $parserParameters = CRM_Contact_Import_Parser_Contact
::getParameterForParser(count($mapper));
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');
132 $locationTypes = array('Primary' => ts('Primary')) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Address', 'location_type_id');
134 foreach ($mapper as $key => $value) {
136 $fldName = CRM_Utils_Array
::value(0, $mapper[$key]);
137 $header = array($this->_mapFields
[$fldName]);
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;
143 //need to differentiate non location elements.
144 // @todo merge this with duplicate code on MapField class.
145 if ($selOne && (is_numeric($selOne) ||
$selOne === 'Primary')) {
146 if ($fldName == 'url') {
147 $header[] = $websiteTypes[$selOne];
148 $parserParameters['mapperWebsiteType'][$key] = $selOne;
151 $header[] = $locationTypes[$selOne];
152 $parserParameters['mapperLocType'][$key] = $selOne;
153 if ($selTwo && is_numeric($selTwo)) {
154 if ($fldName == 'phone') {
155 $header[] = $phoneTypes[$selTwo];
156 $parserParameters['mapperPhoneType'][$key] = $selTwo;
158 elseif ($fldName == 'im') {
159 $header[] = $imProviders[$selTwo];
160 $parserParameters['mapperImProvider'][$key] = $selTwo;
166 $fldNameParts = explode('_', $fldName, 3);
167 $id = $fldNameParts[0];
168 $first = isset($fldNameParts[1]) ?
$fldNameParts[1] : NULL;
169 $second = isset($fldNameParts[2]) ?
$fldNameParts[2] : NULL;
170 if (($first == 'a' && $second == 'b') ||
171 ($first == 'b' && $second == 'a')
174 $header[] = ucwords(str_replace("_", " ", $selOne));
176 $relationType = new CRM_Contact_DAO_RelationshipType();
177 $relationType->id
= $id;
178 $relationType->find(TRUE);
179 $parserParameters['relatedContactType'][$key] = $relationType->{"contact_type_$second"};
181 $parserParameters['mapperRelated'][$key] = $fldName;
183 $parserParameters['relatedContactDetails'][$key] = $selOne;
185 if ($selOne == 'url') {
186 $header[] = $websiteTypes[$selTwo];
187 $parserParameters[$key]['relatedContactWebsiteType'][$key] = $selTwo;
190 $header[] = $locationTypes[$selTwo];
191 $parserParameters['relatedContactLocType'][$key] = $selTwo;
193 if ($selOne == 'phone') {
194 $header[] = $phoneTypes[$selThree];
195 $parserParameters['relatedContactPhoneType'][$key] = $selThree;
197 elseif ($selOne == 'im') {
198 $header[] = $imProviders[$selThree];
199 $parserParameters['relatedContactImProvider'][$key] = $selThree;
206 $mapperFields[] = implode(' - ', $header);
209 $this->_parser
= new CRM_Contact_Import_Parser_Contact(
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']
224 $this->_parser
->run($this->_tableName
, $mapperFields,
225 CRM_Import_Parser
::MODE_IMPORT
,
227 $this->_primaryKeyName
,
228 $this->_statusFieldName
,
231 $this->_totalRowCount
,
232 $this->_doGeocodeAddress
,
233 CRM_Contact_Import_Parser
::DEFAULT_TIMEOUT
,
234 $this->_contactSubType
,
238 $contactIds = $this->_parser
->getImportedContacts();
240 //get the related contactIds. CRM-2926
241 $relatedContactIds = $this->_parser
->getRelatedImportedContacts();
242 if ($relatedContactIds) {
243 $contactIds = array_merge($contactIds, $relatedContactIds);
245 $form->set('relatedCount', count($relatedContactIds));
249 if ($this->_newGroupName ||
count($this->_groups
)) {
250 $groupAdditions = $this->_addImportedContactsToNewGroup($contactIds,
251 $this->_newGroupName
,
252 $this->_newGroupDesc
,
256 $form->set('groupAdditions', $groupAdditions);
260 if ($this->_newTagName ||
!empty($this->_tag
)) {
261 $tagAdditions = $this->_tagImportedContactsWithNewTag($contactIds,
266 $form->set('tagAdditions', $tagAdditions);
274 public function setFormVariables($form) {
275 $this->_parser
->set($form, CRM_Import_Parser
::MODE_IMPORT
);
279 * Add imported contacts.
281 * @param array $contactIds
282 * @param string $newGroupName
283 * @param string $newGroupDesc
284 * @param string $newGroupType
288 private function _addImportedContactsToNewGroup(
290 $newGroupName, $newGroupDesc, $newGroupType
296 /* Create a new group */
297 $newGroupType = isset($newGroupType) ?
$newGroupType : array();
299 'title' => $newGroupName,
300 'description' => $newGroupDesc,
301 'group_type' => $newGroupType,
304 $group = CRM_Contact_BAO_Group
::create($gParams);
305 $this->_groups
[] = $newGroupId = $group->id
;
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;
318 $name = $this->_allGroups
[$groupId];
321 $groupAdditions[] = array(
322 'url' => CRM_Utils_System
::url('civicrm/group/search',
323 'reset=1&force=1&context=smog&gid=' . $groupId
326 'added' => $totalCount,
327 'notAdded' => $addCount[2],
331 return $groupAdditions;
338 * @param string $newTagName
343 private function _tagImportedContactsWithNewTag(
345 $newTagName, $newTagDesc
350 /* Create a new Tag */
353 'name' => $newTagName,
354 'description' => $newTagDesc,
355 'is_selectable' => TRUE,
356 'used_for' => 'civicrm_contact',
359 $addedTag = CRM_Core_BAO_Tag
::add($tagParams, $id);
360 $this->_tag
[$addedTag->id
] = 1;
364 if (is_array($this->_tag
)) {
365 $tagAdditions = array();
366 foreach ($this->_tag
as $tagId => $val) {
367 $addTagCount = CRM_Core_BAO_EntityTag
::addEntitiesToTag($contactIds, $tagId, 'civicrm_contact', FALSE);
368 $totalTagCount = $addTagCount[1];
369 if (isset($addedTag) && $tagId == $addedTag->id
) {
370 $tagName = $newTagName;
374 $tagName = $this->_allTags
[$tagId];
377 $tagAdditions[] = array(
378 'url' => CRM_Utils_System
::url('civicrm/contact/search',
379 'reset=1&force=1&context=smog&id=' . $tagId
382 'added' => $totalTagCount,
383 'notAdded' => $addTagCount[2],
387 return $tagAdditions;